Unique (indices) method similar to MATLAB

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()
1 Like