# Iterator over upper triangular part of Cartesian product?

Is a (preferably efficient) implementation of the following available in some package?

``````triiter(x) = ((a, b) for a in enumerate(x) for b in Iterators.drop(x, a))
``````
``````julia> collect(triiter('a':'d'))
6-element Vector{Tuple{Char, Char}}:
('a', 'b')
('a', 'c')
('a', 'd')
('b', 'c')
('b', 'd')
('c', 'd')
``````

``````julia> using Combinatorics

julia> collect(combinations('a':'d', 2))
6-element Vector{Vector{Char}}:
['a', 'b']
['a', 'c']
['a', 'd']
['b', 'c']
['b', 'd']
['c', 'd']
``````

That has the advantage of being in widely-used package. But, it’s not very performant

``````using Combinatorics

combiter(x) = combinations(x, 2)

triiter(x) = ((a, b) for a in enumerate(x) for b in Iterators.drop(x, a))

isrelprime(x, y) = gcd(x, y) == 1
``````
``````julia> @btime all(x -> isrelprime(x...), combiter((1,3,7,11)));
508.378 ns (13 allocations: 864 bytes)

julia> @btime all(x -> isrelprime(x...), triiter((1,3,7,11)));
58.625 ns (0 allocations: 0 bytes)
``````
1 Like

``````triiter(it) = ((a,b) for (n,b) in enumerate(it) for a in take(n, it))
then realized it’s basically the same as the OP. Oops 