# Does a \`filterfirst\` or \`filtersingle\` function exist? Similar to c# Single()?

**URL:** https://discourse.julialang.org/t/does-a-filterfirst-or-filtersingle-function-exist-similar-to-c-single/88690
**Category:** General Usage
**Created:** [October 13, 2022, 8:47pm UTC](https://discourse.julialang.org/t/does-a-filterfirst-or-filtersingle-function-exist-similar-to-c-single/88690 "2022-10-13T20:47:32Z")
**Posts on this page:** 17
**Page:** 1

<div class="post-metadata">

### Author: ![Brad\_Carman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/brad_carman/32/17631_2.png) [@Brad\_Carman](https://discourse.julialang.org/u/Brad_Carman)
#### Post date: [October 13, 2022, 8:47pm UTC](https://discourse.julialang.org/t/does-a-filterfirst-or-filtersingle-function-exist-similar-to-c-single/88690/1 "2022-10-13T20:47:32Z")

</div>

I’m wondering if the following functions already exist in Julia with another name? I’m often trying to grab a single element, so I find myself writing `filter(...) -> first` a lot, but this is not safe because if the filter call returns an empty array, then I need to handle that case. c# has a linq function call `Single()` which returns the single object which satisfies the criteria, if more than one element match an exception is returned, otherwise nothing is returned.

```julia
function filterfirst(f,items)
    for item in items
        if f(item)
            return item
        end
    end

    return nothing
end

function filtersingle(f,items::Vector{T}) where T
    
    found = T[]
    for item in items
        if f(item)
            push!(found, item)
        end
    end

    n = length(found)

    if n == 0
        return nothing
    elseif n == 1
        return found[1]
    elseif n > 1
        error("Found $n items, expected 1")
    end

end

```

Anyone know where these might already exist?

---

<div class="post-metadata">

### Author: ![josuagrw](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/josuagrw/32/1015_2.png) [@josuagrw](https://discourse.julialang.org/u/josuagrw)
#### Post date: [October 13, 2022, 8:56pm UTC](https://discourse.julialang.org/t/does-a-filterfirst-or-filtersingle-function-exist-similar-to-c-single/88690/2 "2022-10-13T20:56:40Z")

</div>

Is this (part of) what you are looking for?

[https://docs.julialang.org/en/v1/base/arrays/#Base.findfirst-Tuple{Function,%20Any}](https://docs.julialang.org/en/v1/base/arrays/#Base.findfirst-Tuple%7BFunction,%20Any%7D)

---

<div class="post-metadata">

### Author: ![Brad\_Carman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/brad_carman/32/17631_2.png) [@Brad\_Carman](https://discourse.julialang.org/u/Brad_Carman)
#### Post date: [October 13, 2022, 8:57pm UTC](https://discourse.julialang.org/t/does-a-filterfirst-or-filtersingle-function-exist-similar-to-c-single/88690/3 "2022-10-13T20:57:58Z")

</div>

Almost, except I’d like the `object` returned, rather than the `index`

---

<div class="post-metadata">

### Author: ![qwerty](https://avatars.discourse-cdn.com/v4/letter/q/4491bb/32.png) [@qwerty](https://discourse.julialang.org/u/qwerty)
#### Post date: [October 13, 2022, 9:03pm UTC](https://discourse.julialang.org/t/does-a-filterfirst-or-filtersingle-function-exist-similar-to-c-single/88690/4 "2022-10-13T21:03:28Z")

</div>

```julia
using Base.Iterators: take, filter

a = 1:10
div_5(x) = iszero(x % 5)
only(take(filter(div_5, a), 2)) # ArgumentError
a = 1:9
only(take(filter(div_5, a), 2)) # 5

```

* * *

```julia
function my_single(a, f)
    res = Iterators.take(Iterators.filter(f, a), 2)
    isempty(res) && return nothing
    only(res)
end

```

---

<div class="post-metadata">

### Author: ![josuagrw](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/josuagrw/32/1015_2.png) [@josuagrw](https://discourse.julialang.org/u/josuagrw)
#### Post date: [October 13, 2022, 9:05pm UTC](https://discourse.julialang.org/t/does-a-filterfirst-or-filtersingle-function-exist-similar-to-c-single/88690/5 "2022-10-13T21:05:25Z")

</div>

I would approach in a similar way

```julia
julia> a = [1, 4, 2, 2]
4-element Vector{Int64}:
 1
 4
 2
 2

julia> first(Iterators.filter(iseven, a))
4

```

---

<div class="post-metadata">

### Author: ![digital\_carver](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/digital_carver/32/33818_2.png) [@digital\_carver](https://discourse.julialang.org/u/digital_carver)
#### Post date: [October 13, 2022, 10:37pm UTC](https://discourse.julialang.org/t/does-a-filterfirst-or-filtersingle-function-exist-similar-to-c-single/88690/6 "2022-10-13T22:37:46Z")

</div>

`filterfirst` can be written as

```julia
filter(f, a) |> fila -> get(fila, firstindex(fila), nothing)

```

but your version is more efficient since it returns immediately on finding a match.

For `filtersingle`, instead of collecting all items and then checking at the end, you can collect just the one item you might want to return, and error immediately if there’s more than one.

```julia
julia> function filtersingle(f,items::Vector{T}) where T
           
           local found::T
           for item in items
               if f(item)
                   @isdefined(found) && error("Found more than one matching item")
                   found = item
               end
           end
           return (@isdefined(found) ? found : nothing)

       end

```

---

<div class="post-metadata">

### Author: ![josuagrw](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/josuagrw/32/1015_2.png) [@josuagrw](https://discourse.julialang.org/u/josuagrw)
#### Post date: [October 14, 2022, 10:31am UTC](https://discourse.julialang.org/t/does-a-filterfirst-or-filtersingle-function-exist-similar-to-c-single/88690/7 "2022-10-14T10:31:48Z")

</div>

I’ve noticed this before — `Base` is missing a function like

```julia
robustfirst(x) = isempty(x) ? nothing : first(x)

```

which returns `nothing` instead of raising an exception. Does anyone know why we don’t have that?

---

<div class="post-metadata">

### Author: ![josuagrw](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/josuagrw/32/1015_2.png) [@josuagrw](https://discourse.julialang.org/u/josuagrw)
#### Post date: [October 14, 2022, 12:40pm UTC](https://discourse.julialang.org/t/does-a-filterfirst-or-filtersingle-function-exist-similar-to-c-single/88690/8 "2022-10-14T12:40:17Z")

</div>

I’m guessing I can answer this myself: Without the exception it would be impossible to discern if a collection is empty or if it simply has `Nothing` as its first element.

---

<div class="post-metadata">

### Author: ![Brad\_Carman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/brad_carman/32/17631_2.png) [@Brad\_Carman](https://discourse.julialang.org/u/Brad_Carman)
#### Post date: [October 14, 2022, 1:03pm UTC](https://discourse.julialang.org/t/does-a-filterfirst-or-filtersingle-function-exist-similar-to-c-single/88690/9 "2022-10-14T13:03:46Z")

</div>

So it seems if we want the functionality of `filterfirst` or `filtersingle`, one must write their own function or combined expression. Is this worth a PR to include in the Julia language?

---

<div class="post-metadata">

### Author: ![josuagrw](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/josuagrw/32/1015_2.png) [@josuagrw](https://discourse.julialang.org/u/josuagrw)
#### Post date: [October 14, 2022, 1:42pm UTC](https://discourse.julialang.org/t/does-a-filterfirst-or-filtersingle-function-exist-similar-to-c-single/88690/10 "2022-10-14T13:42:20Z")

</div>

I don’t think it’s worth opening a PR—as I noted above, (unlike for `findfirst`) there is no obvious behavior for `filterfirst` when the collection has no matching element. So it is unlikely that folks will come to an agreement about the implementation

---

<div class="post-metadata">

### Author: ![Brad\_Carman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/brad_carman/32/17631_2.png) [@Brad\_Carman](https://discourse.julialang.org/u/Brad_Carman)
#### Post date: [October 14, 2022, 1:48pm UTC](https://discourse.julialang.org/t/does-a-filterfirst-or-filtersingle-function-exist-similar-to-c-single/88690/11 "2022-10-14T13:48:26Z")

</div>

My thinking is `findfirst` returns `nothing` when no match exists, therefore `fitlerfirst` would do the same thing.

The `find..` functions are for returning `indexes`, the `filter..` functions are for returning the `elements`. Just seems to me like a missing feature. Other languages implement such a thing.

---

<div class="post-metadata">

### Author: ![josuagrw](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/josuagrw/32/1015_2.png) [@josuagrw](https://discourse.julialang.org/u/josuagrw)
#### Post date: [October 14, 2022, 1:58pm UTC](https://discourse.julialang.org/t/does-a-filterfirst-or-filtersingle-function-exist-similar-to-c-single/88690/12 "2022-10-14T13:58:17Z")

</div>

A collection cannot have an index `nothing` — so there is a clear interpretation for that return value.

However, a collection can have an element `nothing`:

```julia
julia> a = [1, nothing, 2, 3]
4-element Vector{Union{Nothing, Int64}}:
 1
  nothing
 2
 3

julia> first(Iterators.filter(isnothing, a)) |> println
nothing

```

So now it’s unclear: Did I find a matching element which happens to have the value `nothing`? Or was there no matching element at all? And, in the first place, why should the return value “no matching element” be `nothing` rather than `missing`?

All of these questions are quite unclear…

---

<div class="post-metadata">

### Author: ![Brad\_Carman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/brad_carman/32/17631_2.png) [@Brad\_Carman](https://discourse.julialang.org/u/Brad_Carman)
#### Post date: [October 15, 2022, 1:47pm UTC](https://discourse.julialang.org/t/does-a-filterfirst-or-filtersingle-function-exist-similar-to-c-single/88690/13 "2022-10-15T13:47:05Z")

</div>

OK, makes sense. I guess the best option is to put the code in a separate package. So that’s what I did 🙂

[bradcarman/FilterHelpers.jl: A place to add some missing filter functions: filterfirst, filtersingle, filterlast, etc. (github.com)](https://github.com/bradcarman/FilterHelpers.jl)

---

<div class="post-metadata">

### Author: ![Dan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dan/32/42581_2.png) [@Dan](https://discourse.julialang.org/u/Dan)
#### Post date: [October 15, 2022, 2:46pm UTC](https://discourse.julialang.org/t/does-a-filterfirst-or-filtersingle-function-exist-similar-to-c-single/88690/14 "2022-10-15T14:46:12Z")

</div>

Another implementation of FilterHelper functions, using almost one-liners:

```julia
struct NotUniqueError <: Exception end
filterfirst(f, a) = 
  isnothing(begin pos = findfirst(f,a) ; end) ? nothing : @inbounds a[pos]                                                       
filterlast(f, a) = 
  filterfirst(f, reverse(a))                         
filteronly(f, a) = 
  (r = findfirst(f,a)) == findlast(f,a) ?
  ifelse(isnothing(r),r,@inbounds a[r]) :
  ( @error "More than 1 items" ; throw(NotUniqueError()) )

```

Both `filterfirst` and `filterlast` avoid all item pass. And even `filteronly` in case of too many matching items.

---

<div class="post-metadata">

### Author: ![CameronBieganek](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cameronbieganek/32/6915_2.png) [@CameronBieganek](https://discourse.julialang.org/u/CameronBieganek)
#### Post date: [October 15, 2022, 2:55pm UTC](https://discourse.julialang.org/t/does-a-filterfirst-or-filtersingle-function-exist-similar-to-c-single/88690/15 "2022-10-15T14:55:59Z")

</div>

Some related discussion here:

> <https://github.com/JuliaLang/julia/issues/44996>
>
> \_EDIT: Title changed base on feedback from @nlw0.\_ 
> 
> I often find myself wishi…ng 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
> 
> \`\`\`julia
> very\_long\_name\[findfirst(f, very\_long\_name)\]
> \`\`\`
> 
> Furthermore, \`findfirst(f, A)\` does not work for arbitrary iterators:
> 
> \`\`\`julia
> 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
> julia\> first(Iterators.filter(isodd, itr))
> 5
> \`\`\`
> 
> but 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
> julia\> first(itr, 2)
> 2-element Vector{Int64}:
> 5
> 6
> \`\`\`
> 
> So, I suppose if one wanted \`first(f, itr, n)\` to return an iterator, they would have to use the following instead:
> 
> \`\`\`julia
> 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
> \`\`\`

---

<div class="post-metadata">

### Author: ![CameronBieganek](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cameronbieganek/32/6915_2.png) [@CameronBieganek](https://discourse.julialang.org/u/CameronBieganek)
#### Post date: [October 15, 2022, 3:12pm UTC](https://discourse.julialang.org/t/does-a-filterfirst-or-filtersingle-function-exist-similar-to-c-single/88690/16 "2022-10-15T15:12:43Z")

</div>

> [@josuagrw](#):
>
> So now it’s unclear: Did I find a matching element which happens to have the value `nothing`? Or was there no matching element at all? And, in the first place, why should the return value “no matching element” be `nothing` rather than `missing`?

I think the accepted way to handle this in Base is to return a `Union{Some{T}, Nothing}`. However, I’m not sure if any functions in the public API for Base/stdlib Julia have actually adopted this approach…

---

<div class="post-metadata">

### Author: ![jar1](https://avatars.discourse-cdn.com/v4/letter/j/c0e974/32.png) [@jar1](https://discourse.julialang.org/u/jar1)
#### Post date: [October 15, 2022, 8:09pm UTC](https://discourse.julialang.org/t/does-a-filterfirst-or-filtersingle-function-exist-similar-to-c-single/88690/17 "2022-10-15T20:09:25Z")

</div>

`filtersingle` could be called `only(f, xs)`.
