Reputation: 89
I'm new to Kotlin and would like to combine all elements of a list.
I tried zipWithNext, but it combines an element only with the next one.
val letters = ('a'..'f').toList()
val pairs = letters.zipWithNext()
println(letters) // [a, b, c, d, e, f]
println(pairs) // [(a, b), (b, c), (c, d), (d, e), (e, f)]
I'd like something like this:
From this [a, b, c, d] to this [(a, b), (a, c), (a, d), (b, a), (b, c), (b, d), (c, a), (c, b), (c, d), (d, a), (d, b), (d, c)]
It can be done in imperative way, but I was wonder how to do it in a functional way.
Upvotes: 0
Views: 881
Reputation: 19524
If you're ok with not doing it all in one pipeline (and honestly I'd encourage people to break things down into smaller, well-named functions more often!) you can do something like
val letters = ('a'..'f').toList()
fun allPairs(c: Char) = letters.map { Pair(c, it) }
val combos = letters.flatMap(::allPairs)
print(combos)
or
fun allPairs(c: Char) = letters.filterNot { it == c }.map { Pair(c, it) }
if you don't want duplicates
Upvotes: 1
Reputation: 35482
You can use flatMap
and withIndex
to take the cartesian product with every element other than itself:
fun main() {
val letters = ('a'..'d').toList()
val pairs = letters.withIndex().flatMap { (i1, e1) ->
letters.withIndex().filter { (i2, e2) ->
i1 != i2
}.map { (i2, e2) ->
Pair(e1, e2)
}
}
println(letters) // [a, b, c, d]
println(pairs) // [(a, b), (a, c), (a, d), (b, a), (b, c), (b, d), (c, a), (c, b), (c, d), (d, a), (d, b), (d, c)]
}
Upvotes: 1