0

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
  }
4

2 回答 2

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())
}
于 2013-02-09T00:29:59.280 回答
0

元组列表可以看作是键值对的列表。这让我想起了 Map 类型。显然,使用 ScalaZ 可以累积 Map:Using scala Maps to accumulating values

我还没有学到足够的 ScalaZ(函数式编程)来给你一个工作示例,但你似乎有使用 Haskell 的经验,并且可能有足够的知识来使用 ScalaZ 做到这一点。

于 2013-02-09T13:08:55.493 回答