Scala中BitSet集合数据的聚合

时间:2014-08-15 00:46:23

标签: scala scala-collections bitset

我有一个函数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)) 
}

2 个答案:

答案 0 :(得分:2)

如果我理解正确的话,这个单行应该这样做:

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

(从地图生成所有单个BitSet,然后使用reduce连接它们)

答案 1 :(得分:1)

你会说foldLeftforeach更好。

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
  }
  1. 通过压缩/加入当前来自给定集合的每个值以及来自List[(Int, Int)]的相应值来创建l
  2. 对于联接中的每个元组,创建一个不可变集,通过将f的结果附加到前一个集来创建。
  3. 如下所示,没有第一个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