# First matching element in collection

**URL:** https://discourse.julialang.org/t/first-matching-element-in-collection/18324
**Category:** General Usage
**Tags:** question
**Created:** [December 5, 2018, 2:48pm UTC](https://discourse.julialang.org/t/first-matching-element-in-collection/18324 "2018-12-05T14:48:57Z")
**Posts on this page:** 4
**Page:** 1

<div class="post-metadata">

### Author: ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)
#### Post date: [December 5, 2018, 2:48pm UTC](https://discourse.julialang.org/t/first-matching-element-in-collection/18324/1 "2018-12-05T14:48:57Z")

</div>

Sometimes I want to find the first element in a collection that satisfies some predicate `f`. The collection may not be (O(1)) indexable, so `findfirst` then lookup is not ideal.

I am looking for something like

```julia
function firstmatching(f, itr)
    state = ()
    while true
        y = iterate(itr, state...)
        y ≡ nothing && return nothing
        elt = first(y)
        f(elt) && return Some(elt)
        state = Base.tail(y)
    end
end

```

Eg

```julia
julia> firstmatching(isodd, (2, 4, 5))
Some(5)

julia> firstmatching(x -> last(x) ≡ :a, [1 => :b, 2 => :c, 3 => :a])
Some(3 => :a)

```

Does something similar exist in `Base`, or a commonly used package?

---

<div class="post-metadata">

### Author: ![bennedich](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bennedich/32/4894_2.png) [@bennedich](https://discourse.julialang.org/u/bennedich)
#### Post date: [December 5, 2018, 3:15pm UTC](https://discourse.julialang.org/t/first-matching-element-in-collection/18324/2 "2018-12-05T15:15:46Z")

</div>

How about `first(Iterators.filter(f, itr))`?

---

<div class="post-metadata">

### Author: ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)
#### Post date: [December 5, 2018, 4:37pm UTC](https://discourse.julialang.org/t/first-matching-element-in-collection/18324/3 "2018-12-05T16:37:55Z")

</div>

> [@bennedich](#):
>
> How about `first(Iterators.filter(f, itr))` ?

I thought about that too, but besides being kind of complicated,

```julia
julia> first(Iterators.filter(isodd, 2:2:10))
ERROR: ArgumentError: collection must be non-empty
Stacktrace:
 [1] first(::Base.Iterators.Filter{typeof(isodd),StepRange{Int64,Int64}}) at ./abstractarray.jl:289
 [2] top-level scope at none:0

```

---

<div class="post-metadata">

### Author: ![bennedich](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bennedich/32/4894_2.png) [@bennedich](https://discourse.julialang.org/u/bennedich)
#### Post date: [December 5, 2018, 7:43pm UTC](https://discourse.julialang.org/t/first-matching-element-in-collection/18324/4 "2018-12-05T19:43:16Z")

</div>

Complicated? I feel like this is precisely the kind of thing `Iterators.filter` was made for. To support `nothing`, you could do:

```julia
function firstmatching2(f, itr)
    it = iterate(Iterators.filter(f, itr))
    it ≡ nothing ? nothing : it[1]
end

```

The advantage of reusing existing code is that you get maintenance, testing and (usually) a decent quality implementation for free. For example:

```julia
julia> A = [0:2:1000000; 1];

julia> @btime firstmatching(isodd, A)
  34.428 ms (1999497 allocations: 38.14 MiB)
Some(1)

julia> @btime firstmatching2(isodd, A)
  334.707 μs (2 allocations: 48 bytes)
1

```

I’m sure you can fix this in your implementation (if it matters to you), but if you reuse existing code, you don’t have to worry about these things.
