在Kotlin中,如何链接任意数量的函数

时间:2018-07-17 09:24:12

标签: kotlin

在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)

2 个答案:

答案 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) }
    }
}