# Iterator over upper triangular part of Cartesian product?

**URL:** <https://discourse.julialang.org/t/iterator-over-upper-triangular-part-of-cartesian-product/63118>\
**Category:** General Usage\
**Tags:** question\
**Created:** [June 17, 2021, 10:32pm UTC](https://discourse.julialang.org/t/iterator-over-upper-triangular-part-of-cartesian-product/63118 "2021-06-17T22:32:09Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![jlapeyre](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jlapeyre/32/4514_2.png) [@jlapeyre](https://discourse.julialang.org/u/jlapeyre)\
**Post date:** [June 17, 2021, 10:32pm UTC](https://discourse.julialang.org/t/iterator-over-upper-triangular-part-of-cartesian-product/63118/1 "2021-06-17T22:32:09Z")

</div>

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

```julia
triiter(x) = ((a[2], b) for a in enumerate(x) for b in Iterators.drop(x, a[1]))

```

```julia
julia> collect(triiter('a':'d'))
6-element Vector{Tuple{Char, Char}}:
 ('a', 'b')
 ('a', 'c')
 ('a', 'd')
 ('b', 'c')
 ('b', 'd')
 ('c', 'd')

```

---

<div class="post-metadata">

**Author:** ![CameronBieganek](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cameronbieganek/32/6915_2.png) [@CameronBieganek](https://discourse.julialang.org/u/CameronBieganek)\
**Post date:** [June 18, 2021, 1:54am UTC](https://discourse.julialang.org/t/iterator-over-upper-triangular-part-of-cartesian-product/63118/2 "2021-06-18T01:54:24Z")

</div>

How about Combinatorics.jl?

```julia
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']

```

---

<div class="post-metadata">

**Author:** ![jlapeyre](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jlapeyre/32/4514_2.png) [@jlapeyre](https://discourse.julialang.org/u/jlapeyre)\
**Post date:** [June 18, 2021, 2:57am UTC](https://discourse.julialang.org/t/iterator-over-upper-triangular-part-of-cartesian-product/63118/3 "2021-06-18T02:57:36Z")

</div>

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

```julia
using Combinatorics

combiter(x) = combinations(x, 2)

triiter(x) = ((a[2], b) for a in enumerate(x) for b in Iterators.drop(x, a[1]))

isrelprime(x, y) = gcd(x, y) == 1

```

```julia
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)

```

---

<div class="post-metadata">

**Author:** ![cscherrer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cscherrer/32/7631_2.png) [@cscherrer](https://discourse.julialang.org/u/cscherrer)\
**Post date:** [June 18, 2021, 4:19am UTC](https://discourse.julialang.org/t/iterator-over-upper-triangular-part-of-cartesian-product/63118/5 "2021-06-18T04:19:12Z")

</div>

I had posted

```julia
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 🙂
