我有一个函数f
,它从两个输入参数返回一个BitSet
给定值列表,我需要从函数f
返回一个连接的BitSet。
例如,对于具有3个元素List(10,20,30)
的值List,该方法应返回如下:
val l = List(100,200,300)
def shiftAndJoin(values:List[Int]) = {
f(10, l(0)) ++
f(20, l(1)) ++
f(30, l(2))
}
简单直观的解决方案可能是使用索引迭代值来聚合BitSet()集合变量,就像这样。但是,我想应该有一种比这更好的方法(某种方式不使用++ =运算符)。
var r = BitSet()
(values zipWithIndex).foreach { case (v, i) =>
r ++= f(v, l(i))
}
答案 0 :(得分:2)
如果我理解正确的话,这个单行应该这样做:
values.zip(l).map{case (v, i) => f(v,i)}.reduce{ _ ++ _ }
(从地图生成所有单个BitSet,然后使用reduce连接它们)
答案 1 :(得分:1)
你会说foldLeft
比foreach
更好。
val l: List[Int] = ???
def shiftAndJoin(values: List[Int]) =
values.zip(l). // 1. zip
foldLeft(immutable.BitSet.empty) { (s, z) => // 2. recursion
val (v, li) = z // tuple from join
s ++ f(v, li) // create updated set
}
List[(Int, Int)]
的相应值来创建l
。f
的结果附加到前一个集来创建。如下所示,没有第一个zip
步骤可以更有效率,在折叠时完成所有操作。
import immutable.BitSet
(values.foldLeft(0 -> BitSet.empty) { (st, v) =>
val (i, s) = st
(i+1) -> s ++ l.lift(i)./*get Option[Int] from l*/
fold(BitSet.empty/*no new elements as nothing in l at index i*/)(f(v, _)/*new from f*/)
})._2 // BitSet from last fold state