作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
要创建两组参数的所有可能组合并对它们执行操作,您可以执行以下操作:
setOf(foo, bar, baz).forEach { a ->
setOf(0, 1).forEach { b ->
/* use a and b */
}
}
setOf(foo, bar, baz).forEach { a ->
setOf(0, 1).forEach { b ->
setOf(true, false, null).forEach { c ->
setOf("Hello,", "World!").forEach { d ->
/* use a, b, c and d */
}
}
}
}
for
类似地写这个循环,或者像这样不同:
val dAction = { d: String -> /* use a, b, c and d */ }
val cAction = { c: Boolean? -> setOf("Hello,", "World!").forEach(dAction) }
val bAction = { b: Int -> setOf(true, false, null).forEach(cAction) }
val aAction = { a: Any? -> setOf(0, 1).forEach(bAction) }
setOf(foo, bar, baz).forEach(aAction)
{ /* use a, b, c and d */
for a in setOf(foo, bar, baz),
for b in setOf(0, 1),
for c in setOf(true, false, null),
for d in setOf("Hello,", "World!")
}
flatMap
-
flatMap
-...-
flatMap
-
map
.
最佳答案
我自己创建了一个解决方案,所以我不必按照 Omar's answer 的建议添加依赖项.
我创建了一个需要两组或更多组任意大小的函数:
fun cartesianProduct(a: Set<*>, b: Set<*>, vararg sets: Set<*>): Set<List<*>> =
(setOf(a, b).plus(sets))
.fold(listOf(listOf<Any?>())) { acc, set ->
acc.flatMap { list -> set.map { element -> list + element } }
}
.toSet()
val a = setOf(1, 2)
val b = setOf(3, 4)
val c = setOf(5)
val d = setOf(6, 7, 8)
val abcd: Set<List<*>> = cartesianProduct(a, b, c, d)
println(abcd)
[[1, 3, 5, 6], [1, 3, 5, 7], [1, 3, 5, 8], [1, 4, 5, 6], [1, 4, 5, 7], [1, 4, 5, 8], [2, 3, 5, 6], [2, 3, 5, 7], [2, 3, 5, 8], [2, 4, 5, 6], [2, 4, 5, 7], [2, 4, 5, 8]]
cartesianProduct
返回一组列表。这些列表存在许多问题:
Any?
.该函数返回 Set<List<*>>
,即 Set<List<Any?>>
. Pair
或 Triple
,其中大小根据定义是常数。但是,这些列表/元组的大小应等于输入集的数量,即上例中的 4。 data class Parameters(val number: Int, val maybe: Boolean?) {
override fun toString() = "number = $number, maybe = $maybe"
}
val e: Set<Int> = setOf(1, 2)
val f: Set<Boolean?> = setOf(true, false, null)
val parametersList: List<Parameters> = cartesianProduct(e, f).map { ::Parameters.call(*it.toTypedArray()) }
println(parametersList.joinToString("\n"))
number = 1, maybe = true
number = 1, maybe = false
number = 1, maybe = null
number = 2, maybe = true
number = 2, maybe = false
number = 2, maybe = null
::Parameters
)指定了列表内容的契约。
map { ::Parameters.call(*it.toTypedArray()) }
不是很好,我创建了第二个扩展函数来为我做这件事:
fun <T> Set<List<*>>.map(transform: KFunction<T>) = map { transform.call(*it.toTypedArray()) }
val parametersList: List<Parameters> = cartesianProduct(e, f).map(::Parameters)
关于kotlin - 创建 n 元笛卡尔积的惯用方法(多组参数的组合),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53749357/
我是一名优秀的程序员,十分优秀!