假设我有一个这样的列表清单:[["1","2","4"], ["5","6"], ["7"]]
我想编写一个通过从每个子列表中仅取一个数字来返回所有可能的数字序列的函数。
输出示例:[["1","5","7"], ["2","5","7"],["2","5",7"] continue...]
我曾考虑使用多个嵌套循环,但最终结果不会是“好看”。
所以我想知道是否有一种更干净的方法可以使用Kotlin集合API处理此问题
这是我想出的解决方案:
fun test():List<List<String>> {
val test = mutableListOf(listOf("1","2","3"), listOf("5"), listOf("6"))
val result:MutableMap<Int,MutableList<List<String>>> = mutableMapOf()
for(i in test.indices) {
if (!result.containsKey(i)) result[i] = mutableListOf()
if (i == 0) test[i].forEach { result[i]!!.add(listOf(it)) }
else {
if (i-2 >= 0) result.remove(i-2)
result[i-1]!!.forEach {prev ->
test[i].forEach {
result[i]!!.add(prev + listOf(it))
}
}
}
}
return result[test.size-1]
}
这是我根据评论输入修改解决方案的方式,也许将来会对某人有用。
fun test():List<List<String>> {
return result[test.size-1]
}
fun cartesianProduct(input: List<List<*>>): List<List<*>> {
if (input.isEmpty()) return listOf()
return if (input.size == 1) input[0].map { listOf(it) }
else {
val a = input[0]
val b = input[1]
val rest = input.filterIndexed{index, set -> index>1 }.toSet()
(setOf(a, b).plus(rest))
.fold(listOf(listOf<Any?>())) { acc, set ->
acc.flatMap { list -> set.map { element -> list + element } }
}
}
}
这里是answer here的一个版本,适用于更多用途:
fun <T> Collection<Iterable<T>>.getCartesianProduct(): List<List<T>> =
if (isEmpty()) emptyList()
else drop(1).fold(first().map(::listOf)) { acc, iterable ->
acc.flatMap { list ->
iterable.map(list::plus)
}
}
fun main() {
val input = listOf("124", "56", "7")
val product = input.map(CharSequence::asIterable).getCartesianProduct()
println(product)
}
输出
[[1, 5, 7], [1, 6, 7], [2, 5, 7], [2, 6, 7], [4, 5, 7], [4, 6, 7]]