Reputation: 7875
In Kotlin, how do I apply an arbitrary number of mapping functions to a given input in a way that passes the output of each mapping function as the input to the next function?
e.g.
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)
Upvotes: 4
Views: 1299
Reputation: 9620
You could do it in a functional way with fold
:
fun applyProcessors(items: List<Item>, itemProcessors: List<(Item) -> Item>): List<Item> {
return items.map {
itemProcessors.fold(it) { acc, processor -> processor(acc) }
}
}
Upvotes: 3
Reputation: 6495
A simple loop through the processors would do:
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
}
}
Upvotes: 2