# Finding Position of Element in an Array

But you still didn’t read the documentation… this would work:

``````a = [ "a", "b", "c", "d" ]
findfirst(isequal("c"), a)
``````
6 Likes

Slightly neater and more legible than my reinvention of the `isequal` function …

Thank you.

But there is a difference between not reading the documentation, which is in the link below and does not mention “isequal” anywhere, and not knowing how to combine different functions to obtain the desired result.

https://docs.julialang.org/en/v1/base/strings/#Base.findfirst-Tuple{AbstractString,AbstractString}

That’s the link to searching inside a string. You are searching in an array.

2 Likes

As @DNF pointed out, you were looking at the docs for another method.

In general, it is better to use `?findfirst` at the REPL, that way you don’t miss the right method.

2 Likes

@nilshg: `isequal` and `==` are not the same. You can read about the difference in the `isequal` doumentation. In this case you could also write `findfirst(==("c"), a)` to get the same result.

2 Likes

findall command does not work at all.

v=rand(Float64,3);
C = findall(x->x==min(v), v)

``````julia> v=rand(3)
3-element Array{Float64,1}:
0.09242010387818334
0.0444175027161271
0.32294884973200766

julia> C = findall(x->x==min(v), v)
ERROR: MethodError: no method matching min(::Array{Float64,1})
``````

how can we find the minimal value position in Julia?

Please try to read the error message. It tells you what’s wrong, it doesn’t have anything to do with `findall`, but with `min`. Use `minimum` instead.

If you only need the position of the first minimum (not all of them), you can use `findmin(v)` instead.

3 Likes

I think that would call `minimum` for every comparison though, which may not be efficient. Something like

``````findall(isequal(minimum(v)), v)
``````

could avoid that.

3 Likes

Thanks you @Tamas_Papp

Since you said “the minimal position”, maybe you could use `argmin`:

``````help?> argmin
search: argmin

argmin(itr) -> Integer

Return the index of the minimum element in a collection. If there are multiple minimal elements, then the first one will be returned.
``````

just to cooperate with the discusion, some benchmarks:

``````v = rand(10000)
``````
``````julia> @btime argmin(v)
18.699 μs (0 allocations: 0 bytes)
443
``````
``````julia> @btime findall(isequal(minimum(v)), v)
32.300 μs (8 allocations: 320 bytes)
1-element Array{Int64,1}:
443
``````
``````julia> @btime findmin(v)
18.699 μs (1 allocation: 32 bytes)
(7.175518611357568e-5, 443)
``````
``````julia> @btime findall(x->x==minimum(v), v)
239.807 ms (20006 allocations: 312.77 KiB)
1-element Array{Int64,1}:
443
``````

obviusly this applies with the max versions too, so is good to know who actually performs faster.

2 Likes

the local minimum or global minimum is also a question.

All methods gives the global minimum xi that xi <= xj for all xj in a vector x, but findmin and argmin throw the first global min they can find, for example:

``````x=[1,2,3,4,1]

julia> findmin([1,2,3,4,1])
(1, 1)
julia> argmin([1,2,3,4,1])
1
``````

but:

``````julia> findall(isequal(minimum(x)),x)
2-element Array{Int64,1}:
1
5
``````
3 Likes

How can you avoid memory allocation by using findall in a loop?
I have a loop which goes upto 100000 and each time it finds the index of numbers matching a certain criteria.
This is what I am talking about:
`for i = 1:100000; cr = max(0.0, 0.2*sqrt(i) - 20); ftt = findall(x .<= cr); end`

x is an array of floats.

how is `cr` an array?..

maybe you can sort array and find first, since find needs to make comparison

Sorry, I have just edited. x is an array of floats

Pass `findall` a predicate so it doesn’t need to allocate the temporary `x .<= cr` array, i.e. `findall(xi -> xi <= cr, x)`. This produced a ~3x speedup on my machine.

1 Like

Just to say that I wish in v2 we’d have a simpler API for this - most languages have something in the line of `indexof`, where you get the index or -1 if not found (so it would also be type stable). In Julia one is forced to do some weird gymnastics involving some form of `find*` and `Some`. It was quite difficult to understand how to use these (when the previous function was deprecated) and I almost never know how to do it without checking the docs – or rather just searching and copying my code. In my humble opinion, t’s not developer friendly.

(PS - off topic but related - OMG how I wish there would be another name for `occursin`. Oh the time I spent trying to remember the name of this function! “To occur” is really not a commonly used English verb and it’s really hard for a non-native English speaker to remember it. I honestly had to repeat it 100 times at some point, exasperated, to commit it to memory).

2 Likes

You only have to use `Some` if `nothing` is a valid index which is quite rare. Otherwise just `find` / `findall` away?

``````julia> a = [1,2,3,4,5];

julia> findall(isequal(3), a)
1-element Array{Int64,1}:
3

julia> findfirst(isequal(3), a)
3
``````

What would a simpler API be?