Checking the uniqueness of a tuple

I have an array of tuples, i.e. Array{Tuple{Int64, Int64}} which I would like to filter by unique items. That is, my uniqueness criteria for a tuple is that (x_1, x_2) = (x_2, x_1).

So if I have a = [(1, 2), (3, 4), (2, 1)] I basically want a return value of ret = [(1, 2), (3,4)](or equivalently [(3, 4), (2, 1)].

My current solution is simple, but costly in terms for performance. Solution is

 unique(x -> Set(x), tmp) ## get the unique pairs.

where tmp is the array of tuples.

JuMP defines an UnorderedPair; could copy that code, turn your tuples into UnorderedPairs, and use unique/unique!/isunique as usual. I think this should be in Base actually.

https://github.com/JuliaOpt/JuMP.jl/blob/ebf9ff93a03f05327e2d082b1fa1175050c8648c/src/quad_expr.jl#L19-L27

If you know that you only need it for pairs, maybe just sort the tuples

unique(((x, y),) -> x > y ? (y, x) : (x, y), [(1, 2), (3, 4), (2, 1)])

?

In the future it’ll be just unique(sort, ...) once this is merged:
https://github.com/JuliaLang/julia/pull/32710

1 Like

Do you need the original order for anything? If not, it may make sense to just sanitize the input. Eg

struct OrderedPair{T}
    a::T
    b::T
    function OrderedPair(a::T, b::T) where T
        if !isless(a, b)
            b, a = a, b
        end
        new{T}(a, b)
    end
end

OrderedPair(ab::Tuple{T,T}) where {T} = OrderedPair(ab...)

and then

input = [(1, 2), (3, 4), (2, 1)]
ordered = OrderedPair.(input)
unique(ordered)