Unwave sequence,Kotlin函数式/流式习惯用法
我有一个交错数据序列(固定步幅),我想将它减少到每个“结构”的单个值(n*步幅值到n个值) 我可以使用循环写入可变列表,并选择步骤作为读者索引,但我正在寻找更具功能性和可读性的方法。有什么想法吗 例如: 输入序列由RGB三元组(步幅3)组成,输出为灰度 命令式的方式是:Unwave sequence,Kotlin函数式/流式习惯用法,kotlin,sequences,purely-functional,Kotlin,Sequences,Purely Functional,我有一个交错数据序列(固定步幅),我想将它减少到每个“结构”的单个值(n*步幅值到n个值) 我可以使用循环写入可变列表,并选择步骤作为读者索引,但我正在寻找更具功能性和可读性的方法。有什么想法吗 例如: 输入序列由RGB三元组(步幅3)组成,输出为灰度 命令式的方式是: fun greyscale(stream:List<Byte>):List<Byte>{ val out = ArrayList(stream.size / 3) var i = 0; v
fun greyscale(stream:List<Byte>):List<Byte>{
val out = ArrayList(stream.size / 3)
var i = 0; var o = 0
while(i < stream.size)
out[o++]=(stream[i++] + stream[i++] + stream[i++])/3
return out
}
fun灰度(流:列表):列表{
val out=ArrayList(stream.size/3)
变量i=0;变量o=0
而(i
我如何在不显式实现函数和可变容器的情况下制作这样的东西,而完全基于函数扩展,如.map
等?排除了其余元素:
const val N=3
趣味灰度(流:列表)=(0到stream.size/N)
.map{it*N}
.map{stream.subList(it,it+N).sum()/N}
.map(Int::toByte)
输出
[1,2,3,4,5,6]=>[2,5]
[1,2,3,4,5]=>[2]
包括其余要素:
const val N=3
趣味灰度(流:列表)=(0到(stream.size+N-1)/N)
.map{it*N}
.map{stream.subList(it,minOf(stream.size,it+N)).sum()/N}
.map(Int::toByte)
输出
[1,2,3,4,5,6]=>[2,5]
[1,2,3,4,5]=>[2,3]
我能做的最好的事情是:
fun grayscale(rgb:List<Byte>):List<Byte>
= rgb.foldIndexed(
IntArray(rgb.size / 3),
{ idx, acc, i ->
acc[idx / 3] = acc[idx / 3] + i; acc
}).map{ (it / 3).toByte() }
趣味灰度(rgb:List):列表
=rgb.foldIndexed(
内阵列(rgb.size/3),
{idx,acc,i->
acc[idx/3]=acc[idx/3]+i;acc
}).map{(it/3.toByte()}
输出
in:[1,2,3,4,5,6]
输出:[2,5]
使用
ArrayList
和add
和last
的变体,一种可能的方法是根据元素的索引进行分组(在本例中为/3
),并将这些组映射到它们的总和
stream.withIndex()
.groupBy { it.index / 3 }
.toSortedMap()
.values
.map { (it.sumBy { it.value } / 3).toByte() }
同样严格的功能,但使用Rx,可以通过使用
Kotlin 1.2(Milestone 1昨天发布)在集合中引入了chunked
方法。它将集合分成给定大小的块。您可以使用它来实现您的功能:
fun greyscale(stream: List<Byte>): List<Byte> =
stream.chunked(3)
.map { (it.sum() / 3).toByte() }
fun灰度(流:列表):列表=
流。分块(3)
.map{(it.sum()/3).toByte()}
与@marstran的答案类似,在Kotlin 1.2中,您可以使用chunked
函数,但为其提供转换lambda:
fun greyscale(stream: List<Byte>): List<Byte> =
stream.chunked(3) { it.average().toByte() }
fun灰度(流:列表):列表=
stream.chunked(3){it.average().toByte()}
这种变体的优点是它不会为每个三元组实例化一个新列表,而是创建一个列表并在整个操作过程中重用它。
map/reduce/flatMap
?恐怕我不太明白你想做什么。你的投入和期望的产出是什么?你的问题太广泛了。你能描述清楚吗?增加了一个例子。这个问题并不宽泛,它相当抽象,因为它涉及用于多个问题的惯用语/模式。Kotlin 1.2-M1(EAP)定义了新的函数,将有助于解决这一问题。即windowed(size:Int,step:Int)
但也chunked(size:Int)
和pairwise()
用于类似场景。有关详细信息,请参阅。一点也不。:)而且不需要toSortedMap
,因为映射是按迭代顺序排序的。
Observable.from(stream)
.window(3)
.concatMap { it.reduce(Int::plus).toObservable() }
.map { (it / 3).toByte() }
fun greyscale(stream: List<Byte>): List<Byte> =
stream.chunked(3)
.map { (it.sum() / 3).toByte() }
fun greyscale(stream: List<Byte>): List<Byte> =
stream.chunked(3) { it.average().toByte() }