-
-
Notifications
You must be signed in to change notification settings - Fork 5.7k
Description
EDIT: Title changed base on feedback from @nlw0.
I often find myself wishing that we had a version of findfirst(f, A) that just returned the first x for which f(x) is true, rather than returning the index. Granted, you could just write that as A[findfirst(f, A)], but that's less elegant for long array names, like
very_long_name[findfirst(f, very_long_name)]Furthermore, findfirst(f, A) does not work for arbitrary iterators:
julia> itr = Iterators.drop(1:8, 4)
Base.Iterators.Drop{UnitRange{Int64}}(1:8, 4)
julia> findfirst(isodd, itr)
ERROR: MethodError: no method matching keys(::Base.Iterators.Drop{UnitRange{Int64}})We do have the following option,
julia> first(Iterators.filter(isodd, itr))
5but that's somewhat bulky. So, I propose that we add first(f, itr), which should work for arbitrary iterators. While we're at it, I suppose we should also add first(f, itr, n::Integer). That would be expected to return an array, since first(itr, n) returns an array:
julia> first(itr, 2)
2-element Vector{Int64}:
5
6So, I suppose if one wanted first(f, itr, n) to return an iterator, they would have to use the following instead:
julia> Iterators.take(Iterators.filter(isodd, itr), 2)
Base.Iterators.Take{Base.Iterators.Filter{typeof(isodd), Base.Iterators.Drop{UnitRange{Int64}}}}(Base.Iterators.Filter{typeof(isodd), Base.Iterators.Drop{UnitRange{Int64}}}(isodd, Base.Iterators.Drop{UnitRange{Int64}}(1:8, 4)), 2)
julia> Iterators.take(Iterators.filter(isodd, itr), 2) |> collect
2-element Vector{Int64}:
5
7