在Kotlin中,如何以将每个映射函数的输出作为下一个函数的输入的方式传递给给定输入的任意数量的映射函数?
例如
import org.junit.Test
import org.testng.Assert
class SomeTest {
@Test
fun testIt() {
// GIVEN a list of 2 items, all field values are zero
val items = listOf(Item(0, 0), Item(0,0))
// AND a function to increment field 1
val itemProcessor1: (Item) -> Item = {item -> item.copy(field1 = item.field1.inc())}
// AND a function to increment field 2
val itemProcessor2: (Item) -> Item = {item -> item.copy(field2 = item.field2.inc())}
// WHEN
val actual = applyProcessors(items, listOf(itemProcessor1, itemProcessor2))
// THEN we expect all fields to be incremented
val expected = listOf(Item(1, 1), Item(1, 1))
Assert.assertEquals(expected, actual)
}
private fun applyProcessors(items: List<Item>, itemProcessors: List<(Item) -> Item>): List<Item> {
// ??? How to combine the list of itemProcessor functions so that each processed Item is passed on to the next processor?
return items.map { it }
}
}
data class Item(val field1: Int, val field2: Int)
答案 0 :(得分:2)
通过处理器的简单循环即可:
private fun applyProcessors(items: List<Item>, itemProcessors: List<(Item) -> Item>): List<Item> {
return items.map {
var value = it
for (processor in itemProcessors) {
value = processor.invoke(value)
}
value
}
}
答案 1 :(得分:2)
您可以使用fold
以实用的方式进行操作:
fun applyProcessors(items: List<Item>, itemProcessors: List<(Item) -> Item>): List<Item> {
return items.map {
itemProcessors.fold(it) { acc, processor -> processor(acc) }
}
}