Find position of Array elements in another Array

Suppose I have the Array a=[0.5, 0.6, 0.5, 0.4, 0.5, 0.6] and a reference Array b=[0.4, 0.5, 0.6]. I want to to find the position in b of each element of a. I want then to obtain the output [2, 3, 2, 1, 2, 3]. I tried codes like findfirst.(x-> x in b,a) or findfirst.(x-> x.==b,a) but they don’t work. I didn’t find any satisfactory solution in my seraches and attempts. Any hint, guys?

findfirst.(isequal.(a), (b,)) should work.

5 Likes
julia> map(a) do ai
       findfirst(t -> t == ai, b)
       end
1 Like

Gosh! I even tried findfirst(isequal(a),b) but completely forgot the element-wise operations! Didn’t know the , option after b.

Ok :slight_smile: Didn’t know about this application of do.

Just a note on this because it is tricky and does come up. The reason he wrote (b,) is that if you do not wrap the b, Julia tries to also broadcast the findfirst function over b as well. You don’t want that in this case, so you have to “hide” b within something. He put b in a tuple, but you could also use [b] or Ref(b).

4 Likes

That’s just creating a 1-element tuple:

julia> t = (1,)
(1,)

julia> typeof(t)
Tuple{Int64}

You need the , because otherwise (x) is just the same as x.

You can also do Ref(b) instead, since Julia guarantees that a Ref is treated as a scalar in broadcasting.

5 Likes

Gotcha by 2 secs :wink:

2 Likes

Ok, perfect!

Ok got it :slight_smile:

For the curious ones: the goal of the output Array [2, 3, 2, 1, 2, 3] is to apply it to a multidimensional Array like A=rand(5,3,6). I want to select the column 2 in the first element of A, the column 3 in the second element of A and so on :wink: That part of code is ok for me :slight_smile: Just wanted to share the utility of obtaining such an output Array.

There is also indexin(a, b).

6 Likes

OMG! Such a simple solution and command! Didn’t know the existence of this function.

This and invperm I’ve probably re-written with findfirst more often than I remember…

BTW I think indexin may be more efficient if b is large, as it scans just once. But not here.

Ok :slight_smile: Yes, b is not large.

indexin should be the accepted answer! @sergevic can you please change it?

d=Dict(b.=>eachindex(b))
map(e->get(d,e,nothing),a)

PS

:point_up_2: