Scala中位集集合数据的聚合

Scala中位集集合数据的聚合,scala,scala-collections,bitset,Scala,Scala Collections,Bitset,我有一个函数f,它从两个输入参数返回一个位集。 给定值列表,我需要从函数f返回一个连接的位集。 例如,对于包含3个元素的值列表List(10,20,30),该方法应按如下方式返回: val l = List(100,200,300) def shiftAndJoin(values:List[Int]) = { f(10, l(0)) ++ f(20, l(1)) ++ f(30, l(2)) } 简单直观的解决方案可能是使用索引对值进行迭代,从而聚合BitSet()集合变量,如下所

我有一个函数
f
,它从两个输入参数返回一个位集。
给定值列表,我需要从函数
f
返回一个连接的位集。 例如,对于包含3个元素的值列表
List(10,20,30)
,该方法应按如下方式返回:

val l = List(100,200,300)
def shiftAndJoin(values:List[Int]) = {
  f(10, l(0)) ++
  f(20, l(1)) ++
  f(30, l(2))
}
简单直观的解决方案可能是使用索引对值进行迭代,从而聚合BitSet()集合变量,如下所示。然而,我想应该有一种更好的方法(某种不使用+++=运算符的方法)


你会说,
foldLeft
是比
foreach
更好的朋友

val l:List[Int]=???
def shiftAndJoin(值:列表[Int])=
value.zip(l)。//1.拉链
foldLeft(immutable.BitSet.empty){(s,z)=>//2.递归
val(v,li)=z//join中的元组
s++f(v,li)//创建更新集
}
  • 创建一个
    列表[(Int,Int)]
    ,方法是将给定集合中的当前每个值与
    l
    中的相应值压缩/合并
  • 对于join中的每个元组,创建一个不可变集,通过将
    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
    

    如果我理解正确,这一行应该可以:

    values.zip(l).map{case (v, i) => f(v,i)}.reduce{ _ ++ _ }
    

    (从映射生成所有单独的位集,然后使用reduce将它们连接起来)

    我认为第二种方法的性能更差<代码>l.lift.apply(i)很麻烦。首先,如果要使用
    提升
    ,请在
    折叠
    之前提升一次,这样就不会每次都创建新对象。其次,索引是
    List
    上的
    O(n)
    ,因此对于
    l
    ,您将具有二次性能。这也具有二次性能。为什么不用
    l
    代替索引来
    zip
    呢?啊,我没有发现
    l
    也是一个列表,我以为它是一个函数调用!对使用
    l
    压缩更有意义。答案已更新。谢谢
    (as,bs)。压缩映射f reduce(++)
    不知道可以将元组传递给需要两个参数的函数!
    values.zip(l).map{case (v, i) => f(v,i)}.reduce{ _ ++ _ }