I often want to iterator over a iterable in such a way that distinct-index elements are only paired once. This is useful for things like one round round-robin leagues
for i in 1:length(a)-1
for j in i+1:length(a)
ai = a[i]
aj = a[j]
# do something with ai and aj
end
end
But I want something like
for (ai, aj) in StairsIterator(a)
# do something with ai aj
end
2 Likes
I think IterTools.subsets
will do what you’re looking for. Something like:
for (i,j) in IterTools.subsets(1:length(a), Val{2}())
# do something
end
This essentially returns the indices of an upper triangular matrix.
8 Likes
Using Subsets is very elegant. I am glad I asked.
2 Likes
Based on @Alexander_Knudson’s solution for the indices, implementing your StairsIterator
should be straightforward:
using IterTools
using Base.Cartesian
StairIterator(a) = (
(@nextract 2 a d -> a[ids[d]]; @ntuple 2 a)
for ids in IterTools.subsets(1:length(a), Val{2}())
)
a = rand(3)
println(a)
for (ai, aj) in StairIterator(a)
println("ai = $ai\t aj = $aj")
end
1 Like