Here is a pure Julia implementation of MATLAB’s unique
, which returns ic
contrary to the previous answer using GroupSlices
:
uniq(A; dims=1) = begin
@assert ndims(A) ∈ (1, 2)
slA = ndims(A) > 1 ? eachslice(A; dims) : A
ia = unique(i -> slA[i], axes(A, dims))
sort!(ia; by=i -> slA[i])
C = stack(slA[ia]; dims)
slC = ndims(A) > 1 ? eachslice(C; dims) : C
ic = map(r -> findfirst(==(slA[r]), slC), axes(A, dims))
C, ia, ic
end
And basic testing:
using Test
main() = begin
let A = [
3 1
3 3
1 3
3 2
2 3
1 1
1 2
2 3
3 3
3 3
]
C, ia, ic = uniq(A; dims=1)
@test ia == [6, 7, 3, 5, 1, 4, 2]
@test ic == [5, 7, 3, 6, 4, 1, 2, 4, 7, 7]
@test C == A[ia, :]
@test A == C[ic, :]
C, ia, ic = uniq(A'; dims=2)
@test ia == [6, 7, 3, 5, 1, 4, 2]
@test ic == [5, 7, 3, 6, 4, 1, 2, 4, 7, 7]
@test C == A'[:, ia]
@test A' == C[:, ic]
end
let A = [9, 2, 9, 5]
C, ia, ic = uniq(A)
@test ia == [2, 4, 1]
@test ic == [3, 1, 3, 2]
@test C == A[ia]
@test A == C[ic]
end
end
main()