# Problem with searchsortedfirst

**URL:** https://discourse.julialang.org/t/problem-with-searchsortedfirst/73332
**Category:** General Usage
**Created:** [December 19, 2021, 3:55pm UTC](https://discourse.julialang.org/t/problem-with-searchsortedfirst/73332 "2021-12-19T15:55:06Z")
**Posts on this page:** 20
**Page:** 1

<div class="post-metadata">

### Author: ![Jean\_Michel](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jean_michel/32/8282_2.png) [@Jean\_Michel](https://discourse.julialang.org/u/Jean_Michel)
#### Post date: [December 19, 2021, 3:55pm UTC](https://discourse.julialang.org/t/problem-with-searchsortedfirst/73332/1 "2021-12-19T15:55:06Z")

</div>

I have a problem with `searchsortedfirst`. I want to search a list of `Pair{Symbol,Int}` which is sorted by the `Symbol`.

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

julia> searchsortedfirst(a,:b;by=first)
ERROR: MethodError: no method matching iterate(::Symbol)
Closest candidates are:
  iterate(::Union{LinRange, StepRangeLen}) at ~/julia-1.7.0/share/julia/base/range.jl:826
  iterate(::Union{LinRange, StepRangeLen}, ::Integer) at ~/julia-1.7.0/share/julia/base/range.jl:826
  iterate(::T) where T<:Union{Base.KeySet{<:Any, <:Dict}, Base.ValueIterator{<:Dict}} at ~/julia-1.7.0/share/julia/base/dict.jl:695
  ...
Stacktrace:
 [1] first(itr::Symbol)
   @ Base ./abstractarray.jl:418
 [2] lt(o::Base.Order.By{typeof(first), Base.Order.ForwardOrdering}, a::Pair{Symbol, Int64}, b::Symbol)
   @ Base.Order ./ordering.jl:111
 [3] searchsortedfirst
   @ ./sort.jl:184 [inlined]
 [4] searchsortedfirst
   @ ./sort.jl:295 [inlined]
 [5] #searchsortedfirst#4
   @ ./sort.jl:297 [inlined]
 [6] top-level scope
   @ REPL[27]:1

```

Am I misusing `searchsortedfirst`? This is in `julia1.7.0`

---

<div class="post-metadata">

### Author: ![oheil](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oheil/32/220745_2.png) [@oheil](https://discourse.julialang.org/u/oheil)
#### Post date: [December 19, 2021, 4:10pm UTC](https://discourse.julialang.org/t/problem-with-searchsortedfirst/73332/2 "2021-12-19T16:10:44Z")

</div>

I think it has to compare `Pair{Symbol, Int64}` to just a symbol `:b`.  
See for example in contrast:

```julia
julia> searchsortedfirst(a,:b=>2;by=first)
2

```

But the following doesn’t work either:

```julia
julia> a=[:a, :b]
2-element Vector{Symbol}:
 :a
 :b

julia> searchsortedfirst( a, :b ;by=first)
ERROR: MethodError: no method matching iterate(::Symbol)

```

So Symbols seem to have some issue.  
As a first and clumsy attempt to work around, I suggest this:

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

julia> searchsortedfirst( [String(x[1]) for x in a ], String(:b) ;by=first)
2

```

which isn’t the best, I am sure.

---

<div class="post-metadata">

### Author: ![Jean\_Michel](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jean_michel/32/8282_2.png) [@Jean\_Michel](https://discourse.julialang.org/u/Jean_Michel)
#### Post date: [December 19, 2021, 4:16pm UTC](https://discourse.julialang.org/t/problem-with-searchsortedfirst/73332/3 "2021-12-19T16:16:59Z")

</div>

Your example rightly does not work since `first(:a)` is an error. On the other hand `first(:b=>2)`is legal and gives `:b`.

---

<div class="post-metadata">

### Author: ![oheil](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oheil/32/220745_2.png) [@oheil](https://discourse.julialang.org/u/oheil)
#### Post date: [December 19, 2021, 4:19pm UTC](https://discourse.julialang.org/t/problem-with-searchsortedfirst/73332/4 "2021-12-19T16:19:31Z")

</div>

This one is better, by defining lt = lowerthan for your case:

```julia
julia> searchsortedfirst(a, :b; lt = (x,y) -> x[1] < y )
2

```

See

```julia
help?> searchsortedfirst
search: searchsortedfirst searchsortedlast searchsorted

  searchsortedfirst(a, x; by=<transform>, lt=<comparison>, rev=false)
...

```

---

<div class="post-metadata">

### Author: ![Jean\_Michel](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jean_michel/32/8282_2.png) [@Jean\_Michel](https://discourse.julialang.org/u/Jean_Michel)
#### Post date: [December 19, 2021, 4:23pm UTC](https://discourse.julialang.org/t/problem-with-searchsortedfirst/73332/5 "2021-12-19T16:23:39Z")

</div>

I do not want `x[1]<y` but `x[1]<y[1]`. This raises also an error.

---

<div class="post-metadata">

### Author: ![oheil](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oheil/32/220745_2.png) [@oheil](https://discourse.julialang.org/u/oheil)
#### Post date: [December 19, 2021, 4:28pm UTC](https://discourse.julialang.org/t/problem-with-searchsortedfirst/73332/6 "2021-12-19T16:28:15Z")

</div>

It’s about the elements in a versus :b.  
The elements in a are `Pair{Symbol, Int64}`, e.g. `:a=>1`  
In the list of such elements you are looking for the first `:b`

If I am right so far, it’s about comparing a `Pair{Symbol, Int64}` with a `Symbol`, therefor `x[1] vs y` where `x[1]`is the `Symbol` from inside the `Pair`, and `y` is just the Symbol `:b`.

Is this understandable? I am not sure and not good in being short and on the point.

---

<div class="post-metadata">

### Author: ![oheil](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oheil/32/220745_2.png) [@oheil](https://discourse.julialang.org/u/oheil)
#### Post date: [December 19, 2021, 5:00pm UTC](https://discourse.julialang.org/t/problem-with-searchsortedfirst/73332/7 "2021-12-19T17:00:08Z")

</div>

Actually I don’t understand the `by` keyword, as the list is expected to be already sorted…  
So, using `by=first` here, seems to also apply `first` to `:b` which raises the original error. Therefor my idea not using `by` but defining `lt`.

---

<div class="post-metadata">

### Author: ![oheil](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oheil/32/220745_2.png) [@oheil](https://discourse.julialang.org/u/oheil)
#### Post date: [December 19, 2021, 5:01pm UTC](https://discourse.julialang.org/t/problem-with-searchsortedfirst/73332/8 "2021-12-19T17:01:07Z")

</div>

This may clarify a bit more:

```julia
julia> Base.first(s::Symbol)=s

julia> searchsortedfirst(a, :b; by=first)
2

```

---

<div class="post-metadata">

### Author: ![Jean\_Michel](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jean_michel/32/8282_2.png) [@Jean\_Michel](https://discourse.julialang.org/u/Jean_Michel)
#### Post date: [December 19, 2021, 5:06pm UTC](https://discourse.julialang.org/t/problem-with-searchsortedfirst/73332/9 "2021-12-19T17:06:22Z")

</div>

The `:by` keyword tells which part of the objects should be compared.  
I thought that the object to compare would be compared to the `by` part since the following works:

```julia
julia> a=[1=>"a",3=>"b"]
2-element Vector{Pair{Int64, String}}:
 1 => "a"
 3 => "b"

julia> searchsortedfirst(a,3;by=first)
2

```

---

<div class="post-metadata">

### Author: ![oheil](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oheil/32/220745_2.png) [@oheil](https://discourse.julialang.org/u/oheil)
#### Post date: [December 19, 2021, 5:15pm UTC](https://discourse.julialang.org/t/problem-with-searchsortedfirst/73332/10 "2021-12-19T17:15:24Z")

</div>

> [@Jean\_Michel](#):
>
> The `:by` keyword tells which part of the objects should be compared. So `by=first` is the  
> same as `lt=(x,y)->first(x)<first(y)`

Yes, but you are searching for `:b` which is a `Symbol`, and `first(::Symbol)` raises the original error, because a single `Symbol` `:b` is not iterable as it is not a collection.`

```julia
julia> first(:b)
ERROR: MethodError: no method matching iterate(::Symbol)

```

So defining `first` on type `Symbol`, as in my last post, resolves this, but it’s not the recommended solution. The recommended solution is defining the less-than relation between `Pair{Symbol, Int64}` and `Symbol`.  
Now you are editing your replies… this is becoming to awkward, so I think, it’s all said, perhaps not in the best understandable way.

---

<div class="post-metadata">

### Author: ![oheil](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oheil/32/220745_2.png) [@oheil](https://discourse.julialang.org/u/oheil)
#### Post date: [December 19, 2021, 5:17pm UTC](https://discourse.julialang.org/t/problem-with-searchsortedfirst/73332/11 "2021-12-19T17:17:14Z")

</div>

Integer number are per definition iterables:

```julia
julia> first(1)
1

```

There is quite some discussion about this, which I don’t look up for you now, but it is like that.  
Symbols are not iterable.

---

<div class="post-metadata">

### Author: ![Jean\_Michel](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jean_michel/32/8282_2.png) [@Jean\_Michel](https://discourse.julialang.org/u/Jean_Michel)
#### Post date: [December 19, 2021, 5:18pm UTC](https://discourse.julialang.org/t/problem-with-searchsortedfirst/73332/12 "2021-12-19T17:18:46Z")

</div>

I edit my posts when I have written a mistake and hope the edit is before you read.  
I think I understand: the `by` is also applied to the value I want to compare (unfortunately)  
and my last example works by a fluke (that first is valid for an Int).

---

<div class="post-metadata">

### Author: ![oheil](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oheil/32/220745_2.png) [@oheil](https://discourse.julialang.org/u/oheil)
#### Post date: [December 19, 2021, 5:19pm UTC](https://discourse.julialang.org/t/problem-with-searchsortedfirst/73332/13 "2021-12-19T17:19:11Z")

</div>

And I did it anyways:  
[https://github.com/JuliaLang/julia/issues/7903](https://github.com/JuliaLang/julia/issues/7903)

---

<div class="post-metadata">

### Author: ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)
#### Post date: [December 19, 2021, 6:20pm UTC](https://discourse.julialang.org/t/problem-with-searchsortedfirst/73332/14 "2021-12-19T18:20:29Z")

</div>

The discussion got complicated and is solved, but it was not clear to me if it is clear to the reader that this works:

```julia
julia> a=[:a=>1,:b=>2,:b=>3,:c=>4]
4-element Vector{Pair{Symbol, Int64}}:
 :a => 1
 :b => 2
 :b => 3
 :c => 4

julia> searchsortedfirst(a, (:b,); by=first)
2

julia> searchsortedfirst(a, (:c,); by=first)
4

```

(any catch here I don’t see?)

I see now: the order is on the values, not on the keys… (though I’m unsure now, if `by=first`, if that is not what one wants really)

---

<div class="post-metadata">

### Author: ![Jean\_Michel](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jean_michel/32/8282_2.png) [@Jean\_Michel](https://discourse.julialang.org/u/Jean_Michel)
#### Post date: [December 19, 2021, 6:25pm UTC](https://discourse.julialang.org/t/problem-with-searchsortedfirst/73332/15 "2021-12-19T18:25:19Z")

</div>

It works since `first((:b,))` is defined and returns `:b`. I think I projected in my mind a better interface for the `searchsorted...` routines in case of `by` keyword that the actual interface,that is I hoped that the `by` function would not be applied to the value given to compare, which seemed natural.

---

<div class="post-metadata">

### Author: ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)
#### Post date: [December 19, 2021, 6:28pm UTC](https://discourse.julialang.org/t/problem-with-searchsortedfirst/73332/16 "2021-12-19T18:28:30Z")

</div>

Yes, that is catchy. I have been there is some more mundane examples, like:

```julia
julia> searchsortedfirst([1,2,3,4], 2, by=x -> x^2)
2

julia>

```

Sometimes this is very annoying, because it requires one to define the inverse function to be able to search, something that is not always trivial.

---

<div class="post-metadata">

### Author: ![Jean\_Michel](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jean_michel/32/8282_2.png) [@Jean\_Michel](https://discourse.julialang.org/u/Jean_Michel)
#### Post date: [December 19, 2021, 6:30pm UTC](https://discourse.julialang.org/t/problem-with-searchsortedfirst/73332/17 "2021-12-19T18:30:05Z")

</div>

Perhaps change the meaning of `by` in `julia2.0`?

---

<div class="post-metadata">

### Author: ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)
#### Post date: [December 19, 2021, 6:31pm UTC](https://discourse.julialang.org/t/problem-with-searchsortedfirst/73332/18 "2021-12-19T18:31:18Z")

</div>

I think that I was convinced that that is the reasonable behavior, but I don’t remember why. Let me see if I find the thread. (I found the thread, but it was not really related, I just learnt that there, not really with a good justification).

---

<div class="post-metadata">

### Author: ![Jean\_Michel](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jean_michel/32/8282_2.png) [@Jean\_Michel](https://discourse.julialang.org/u/Jean_Michel)
#### Post date: [December 19, 2021, 10:44pm UTC](https://discourse.julialang.org/t/problem-with-searchsortedfirst/73332/19 "2021-12-19T22:44:06Z")

</div>

Perhaps we could ask for a compromise, that is a keyword to the `searchsorted...` function which would signify that the `by` function is _not_ applied to the object to compare.

---

<div class="post-metadata">

### Author: ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)
#### Post date: [December 19, 2021, 11:04pm UTC](https://discourse.julialang.org/t/problem-with-searchsortedfirst/73332/20 "2021-12-19T23:04:45Z")

</div>

```julia
apply =

```

maybe

[Next page](https://discourse.julialang.org/t/problem-with-searchsortedfirst/73332.md?page=2)
