Moritz Groß
Moritz Groß

Reputation: 1490

Kotlin: Iterate through every pair (or generally fixed-sized subsets) in collection

Is there a short/idiomatic way to iterate through every pair of elements in a collection?

Even better would be a method that iterates through all fixed-cardinality subsets of a collection.

The classic and ugly approach would be:

val s = setOf(1, 2, 3, 4)

for (i in s) {
    for (j in s) {
        if (i != j) {
            println("$i $j")
        }
    }
}

For having bigger subsets, more loops are necessary, so this isn't scalable.

Upvotes: 7

Views: 5035

Answers (3)

Tenfour04
Tenfour04

Reputation: 93659

This is technically also O(n^2) but will have a little less than half as many iterations: (n^2 - n) / 2

val l = s.toList()
for (i in s.indices) {
    for (j in i + 1 until s.size) {
        println("${l[i]}, ${l[j]}")
        println("${l[j]}, ${l[i]}")
    }
}

Upvotes: 3

Neo
Neo

Reputation: 2039

I think you got already the most idiomatic way to solve it. If you want to do it more functional, this is what you can convert it to:

s.map { i -> s.map { i to it } }
    .flatten()
    .filter { (left, right) -> left != right }
    .onEach { (i, j) -> println("$i $j") }

Upvotes: 4

aax
aax

Reputation: 454

If you find an implementation of the power set operation, you can take all elements of the power set with length = 2.

Upvotes: 1

Related Questions