Using unique, one can access the indices of unique values by using i = unique(i -> A[i], eachindex(A)), however I don’t know how to modify this for 2D arrays.
Appreciate any guidance. Context is I have a list of (x,y,z) coordinates (Mx3 array) where there are duplicate (x,y) values, and I’m trying to get rid of them. There may be a better way to do this. This issue is preventing me from gridding mesh coordinates using GMT, LinearInterpolations, and other packages.
function distindrow(m)
d=Dict{SubArray{Int64, 1, Matrix{Int64}, Tuple{Int64, Base.Slice{Base.OneTo{Int64}}}, true},Int}()
#d=Dict{Array{Int},Int}()
for (i,e) in enumerate(eachrow(m))
d[e]=i
#d[copy(e)]=i
end
values(d)
end
PS
unlike unique provides the latest index among those that have the same value
use thie version in case
julia> function distind(m)
d=Dict{SubArray{Int64, 1, Matrix{Int64}, Tuple{Int64, Base.Slice{Base.OneTo{Int64}}}, true},Int}()
#d=Dict{Array{Int},Int}()
for (i,e) in enumerate(Iterators.reverse(eachrow(m)))
d[e]=i
#d[copy(e)]=i
end
values(d)
end
distind (generic function with 1 method)
I had tried as you say, but it gave me an error which (due to the rush) I attributed to the fact that the type returned by the eacrow() function could not be replaced by array{Int}.
I take this opportunity to add a different way of obtaining the same result
senza usare il tipo OMG
Although, sometimes, the measurements say that the OMG type is better
julia> function distindOMG2(m)
d=Dict{SubArray{Int64, 1, Matrix{Int64}, Tuple{Int64, Base.Slice{Base.OneTo{Int64}}}, true},Int}()
for (i,e) in enumerate(eachrow(m))
get!(d,e,i)
end
values(d)
end
distindOMG2 (generic function with 1 method)
julia> function distindJustV(m)
d=Dict{Array{Int},Int}()
for (i,e) in enumerate(eachrow(m))
get!(d,e,i)
end
values(d)
end
distindJustV (generic function with 1 method)
julia> @btime distindOMG2($m)
786.667 ns (7 allocations: 4.38 KiB)
ValueIterator for a Dict{SubArray{Int64, 1, Matrix{Int64}, Tuple{Int64, Base.Slice{Base.OneTo{Int64}}}, true}, Int64} with 11 entries. Values:
2
4
8
1
14
20
16
7
10
5
3
julia> @btime distindJustV($m)
2.000 μs (58 allocations: 3.98 KiB)
ValueIterator for a Dict{Array{Int64}, Int64} with 11 entries. Values:
2
4
8
1
14
20
16
7
10
5
3
Instead of writing out the view type, you could use the first element to define it. This should be as efficient:
julia> function distind2(mat::AbstractMatrix)
(i,e), rest = Iterators.peel(zip(axes(mat,1), eachrow(mat)))
d = Dict(e => i)
for (i,e) in rest
d[e] = i
end
values(d)
end
distind2 (generic function with 2 methods)
julia> distind2([1 2; 3 4; 3 4] ./ pi) # any eltype
ValueIterator for a Dict{SubArray{Float64, 1, Matrix{Float64}, Tuple{Int64, Base.Slice{Base.OneTo{Int64}}}, true}, Int64} with 2 entries. Values:
1
3
Often it’s more convenient to use a vector of static vectors to represent such data. In this case, it lets you use unique in the way you were already familiar with: