我只是想为那些无法使用 fold(...)
的情况添加更一般性的方法。因为,为了使用 fold
,你需要能够表达一些初始值。
someIterable
.filter { TODO("possibly filter-out everything") }
.takeIf { it.isNotEmpty() }
?.reduce { acc, element -> TODO("merge operation") }
?: TODO("value or exception for empty")
使用这种方法,在集合为空的情况下,reduce
不会执行,因为 takeIf
会将其转换为 null
。最后,我们可以使用 Elvis 运算符来表示在这种情况下返回某个值(或抛出异常)。
你的示例:
intArrayOf(1, 2, 3)
.filter { a -> a < 0 }
.takeIf { it.isNotEmpty() }
?.reduce { a, b -> a + b }
?: 0
编辑:
自从Kotlin 1.4版以来,有一个标准库函数reduceOrNull
,比.takeIf { it.isNotEmpty() }
方法更适用。
通用情况:
someIterable
.filter { TODO("possibly filter-out everything") }
.reduceOrNull { acc, element -> TODO("merge operation") }
?: TODO("value or exception for empty")
用于解决您的问题:
intArrayOf(1, 2, 3)
.filter { a -> a < 0 }
.reduceOrNull { a, b -> a + b }
?: 0
reduce
来求和,那么你可以在数字列表上使用内置的.sum()
函数;如果你正在对某些特殊的东西进行求和,那么你也可以编写扩展函数来帮助解决问题。 - Richard Green