How to create an array consists of indices of elements in one array that exists in the other array?

I firstly declared 2 arrays:

coord1 = [[0.0, 0.0],
          [1.0, 0.0],
          [0.0, 1.0],
          [1.0, 1.0],
          [0.0, 2.0],
          [1.0, 2.0]]
 
 coord2 =  [[1.0, 0.0],
            [2.0, 0.0],
            [1.0, 1.0],
            [2.0, 1.0]]

I would like to create

  1. an array index1 that consists of indice of elements in coord2 that exist in coord1
  2. an array index2 that consists of indice of elements in coord1 that exist in coord2

I create the below code :

index1 = []
index2 = []

for (index, value) in enumerate(coord2)
    if value in coord1
        a = findfirst(x->x==value, coord1)
        push!(index1,  a)
        push!(index2,  index)
    end
end

Is there any better way towards this problem?

First, if this is an array of 2-component coordinate vectors, I would strongly recommend using an array of StaticArrays instead, e.g.

using StaticArrays
coord2 = [SVector(1.0,0.0), SVector(2.0,0.0), SVector(1.0,1.0), SVector(2.0,1.0)]

which will be vastly more efficient for virtually any computation you might want to perform.

What algorithm you might want to use here depends on how long your coord1 and coord2 arrays are and whether you care about efficiency. The double loop in your implementation has complexity \Theta(N_1 N_2) if your arrays have lengths N_1 and N_2, respectively. If you want something faster for large arrays (or if you just want shorter code) you could, for example, use a dictionary mapping coordinates to indices:

dict1 = Dict(c => i for (i, c) in enumerate(coord1))
dict2 = Dict(c => i for (i, c) in enumerate(coord2))
index1 = [dict2[c] for c in coord1 if haskey(dict2, c)]
index2 = [dict1[c] for c in coord2 if haskey(dict1, c)]
2 Likes

Thank you a lot for your reply! I haven’t known StaticArray before.
I learned new technique to combine dictionary and array.
Just one more question: How to know that which is faster code?
Is it to use @time macro ?

The @time macro is fine for things that take a really long time. For high-resolution timing of smaller tasks, use the BenchmarkTools package. You have to be especially careful (use $ interpolation, as explained in the Benchmark tools manual) when benchmarking code that uses global variables, in order to avoid dynamic-dispatch overhead that occurs in global scope.

2 Likes

Thank you a lot!