Haskell有一个函数accumArray
函数,它通过键对2元组进行分组,然后使用相同的键减少值。 Scala没有,scalaz似乎有一个,但取决于许多其他scalaz功能。
有没有更好的方法在scala中编写accumArray?
详情来自haskell中的这个函数:http://zvon.org/other/haskell/Outputarray/accumArray_f.html
以下是我的实施。感谢。
private def accumArray[A <% Ordered[A], B, C](f: (B, C) => B,
base: B,
bounds: (A, A),
ll: List[(A, C)]): Vector[(A, B)] = {
ll.filter(i => i._1 >= bounds._1 && i._1 <= bounds._2).
groupBy(_._1).
map(e =>
e._1 -> e._2.map(_._2).foldLeft(base)(f)
).
toVector
}
答案 0 :(得分:1)
这是我的解决方案,而不是那么短暂
def accumArray[A <% Ordered[A], B, C](f: (B, C) => B,
base: B,
bounds: (A, A),
xs: Seq[(A, C)]): Vector[(A, B)] = {
@scala.annotation.tailrec
def accum(ys: Seq[(A, C)], zs: Vector[(A, B)]): Vector[(A, B)] =
(ys, zs) match {
case(Seq(), _) => zs
case(((a,c)) +: rs, Vector()) => accum(rs, Vector((a, f(base,c))))
case(((a1,c)) +: rs, vs :+ ((a2,b))) =>
if(a1 == a2) accum(rs, vs :+ (a2, f(b,c)))
else accum(rs, zs :+ (a1, f(base,c)))
}
val (min, max) = bounds
val ys = xs.filter{case(x, _) => x >= min && x <= max}.sortBy(_._1)
accum(ys, Vector())
}
答案 1 :(得分:0)
元组列表可以看作是键值对的列表。这让我想起了Map类型。使用ScalaZ显然可以累积Map:Using scala Maps to accumulate values
我还没有学到足够的ScalaZ(函数式编程)给你一个工作的例子,但是看起来你有使用Haskell的经验,并且可能有足够的知识来使用ScalaZ。