两个列表

时间:2018-01-06 23:37:25

标签: kotlin

鉴于我有两个清单:

val ints = listOf(0, 1, 2)
val strings = listOf("a", "b", "c")

我想要所有可能的元素组合

0a, 1a, 2a, 0b

有一种比以下更优雅的方式:

ints.forEach { int -> 

    strings.forEach { string ->  


        println("$int $string")

    }

}

3 个答案:

答案 0 :(得分:8)

您可以根据flatMap stdlib函数编写这些扩展函数:

// Extensions
fun <T, S> Collection<T>.cartesianProduct(other: Iterable<S>): List<Pair<T, S>> {
    return cartesianProduct(other, { first, second -> first to second })
}

fun <T, S, V> Collection<T>.cartesianProduct(other: Iterable<S>, transformer: (first: T, second: S) -> V): List<V> {
    return this.flatMap { first -> other.map { second -> transformer.invoke(first, second) } }
}

// Example
fun main(args: Array<String>) {
    val ints = listOf(0, 1, 2)
    val strings = listOf("a", "b", "c")

    // So you could use extension with creating custom transformer
    strings.cartesianProduct(ints) { string, int ->
        "$int $string"
    }.forEach(::println)

    // Or use more generic one
    strings.cartesianProduct(ints)
            .map { (string, int) ->
                "$int $string"
            }
            .forEach(::println)
}

答案 1 :(得分:1)

可能的替代方法:

fun <S, T> List<S>.cartesianProduct(other: List<T>) = this.flatMap {
    List(other.size){ i -> Pair(it, other[i]) } 
}

答案 2 :(得分:0)

另一个(可能更容易理解)替代我之前的答案。两者都达到了相同的结果:

fun <S, T> List<S>.cartesianProduct(other: List<T>) = this.flatMap { thisIt ->
    other.map { otherIt ->
        thisIt to otherIt
    }
}