KevinS
KevinS

Reputation: 7875

In Kotlin, how do I chain an arbitrary number of functions

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

Answers (2)

arekolek
arekolek

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

RobCo
RobCo

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

Related Questions