I wanted to find the first line of a matrix which is all -1
s. I am surprised the following does not work.
What is going on here?
julia> findfirst(l->all(y->y==-1,l),eachrow([1 1;-1 -1]))
ERROR: MethodError: no method matching keys(::Base.Generator{Base.OneTo{Int64},Base.var"#192#193"{Array{Int64,2}}})
Closest candidates are:
keys(::Cmd) at process.jl:638
keys(::Core.SimpleVector) at essentials.jl:603
keys(::LibGit2.GitTree) at /home/jmichel/.julia/packages/Revise/nWJXk/src/git.jl:52
...
Stacktrace:
[1] pairs(::Base.Generator{Base.OneTo{Int64},Base.var"#192#193"{Array{Int64,2}}}) at ./abstractdict.jl:134
[2] findfirst(::var"#5#7", ::Base.Generator{Base.OneTo{Int64},Base.var"#192#193"{Array{Int64,2}}}) at ./array.jl:1854
[3] top-level scope at REPL[1]:1
nilshg
February 9, 2021, 12:50pm
2
Broadcast?
julia> findfirst.(l->all(y->y==-1,l),eachrow([1 1;-1 -1]))
2-element Vector{Union{Nothing, Int64}}:
nothing
1
1 Like
The question is not how to do it differently, but why does it not work? By the way, your solution is less efficient than the desired one, since it checks all lines of the matrix (and allocates a vector of booleans).
nilshg
February 9, 2021, 1:11pm
4
Sorry: the reason is that findfirst
doesn’t work with generators, as the error message suggests: https://github.com/JuliaLang/julia/issues/16884
julia> findfirst(x -> x > 5, (i for i ∈ 1:10))
ERROR: MethodError: no method matching keys(::Base.Generator{UnitRange{Int64}, typeof(identity)})
Hence one other way (but again presumably less efficient than it could theoretically be if we iterated over the generator) is to collect:
julia> findfirst(l->all(y->y==-1,l),collect(eachrow([1 1;-1 -1])))
2
I’m sure someone will be along soon to provide an efficient solution…
1 Like
Thank for the pointer to the ticket. It does not seem too difficult to implement findfirst just relying on the
iteration protocol, just having a counter, so I do not understand why it has not been implemented for all iterators…