Functional idiom fold meets your needs: it takes the initial element and then iterates over the other elements, maintaining the accumulated value, which is updated for each element being processed using the function that you provide.
In Kotlin, this is a fold
extension function for Iterable
, Sequence
or Array
.
You can use it as follows:
fun <T : Chain<T>> buildChain(first: T, vararg members: T): T { members.fold(first as T?) { acc, i -> acc?.let { it + i } } return first }
Here first as T?
Is it required that the battery type be deduced as nullable T?
, because plus
in your Chain<T>
returns NULL (by the way, is this necessary?).
You can also use foldRight
, which simply foldRight
in the reverse order:
fun <T : Chain<T>> buildChain(first: T, vararg members: T): T? = (listOf(first) + members) .foldRight(null as T?) { i, acc -> acc?.let { i + acc }; i }
And there is reduce
and reduceRight
with similar semantics, but using the first and last elements, respectively, for the initial value of the battery. Here is an example with reduceRight
:
fun <T : Chain<T>> buildChain(first: T, vararg members: T): T? = (listOf(first) + members).reduceRight { i, acc -> i.apply { plus(acc) } }
source share