Skip to content

Instantly share code, notes, and snippets.

@cy6erGn0m
Created November 12, 2015 14:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cy6erGn0m/2fedfc575e3ca89ab3b1 to your computer and use it in GitHub Desktop.
Save cy6erGn0m/2fedfc575e3ca89ab3b1 to your computer and use it in GitHub Desktop.
Returns a sequence that consists of all possible pair of original list elements, does nothing with potential duplicates
/**
* Returns a sequence that consists of all possible pair of original list elements, does nothing with potential duplicates
* @param skipSamePairs indicates whether it should produce pairs from the same element at both first and second positions
*/
fun <T> List<T>.allPairs(skipSamePairs: Boolean = true): Sequence<Pair<T, T>> = PairsSequence(this, skipSamePairs)
private class PairsSequence<T>(val source: List<T>, val skipSamePairs: Boolean) : Sequence<Pair<T, T>> {
override fun iterator(): Iterator<Pair<T, T>> = PairsIterator(source, skipSamePairs)
}
private class PairsIterator<T>(val source: List<T>, val skipSamePairs: Boolean) : AbstractIterator<Pair<T, T>>() {
private var index = 0
override fun computeNext() {
if (source.isEmpty()) {
done()
return
}
index++
val i1 = index / source.size
val i2 = index % source.size
if (i1 >= source.lastIndex) {
done()
return
}
if (skipSamePairs && i1 == i2) {
return computeNext()
}
setNext(Pair(source[i1], source[i2]))
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment