如何通过相邻对使用非关联函数进行归约

时间:2018-07-06 20:58:08

标签: scala

如何通过相邻对减少集合?

例如,让+为非关联运算符:

(1、2、3、4、5、6)=>((1 + 2)+(3 + 4))+(5 + 6)

(a,b,c,d,e,f,g,h)=>(((a + b)+(c + d))+(((e + f)+(g + h)))< / p>

这个问题类似于this,但是我认为并行集合不适用,因为语义需要确定性的关联运算符。我不太关心并行执行,而是关心实际的关联以构造一个平衡的表达式树。

1 个答案:

答案 0 :(得分:1)

这是一个可以满足您需要的版本,但是会任意对待“剩余”元素(如果当前迭代中的输入数为奇数,则原样保留一个元素):

def nonassocPairwiseReduce[A](xs: List[A], op: (A, A) => A): A = {
  xs match {
    case Nil => throw new IllegalArgumentException
    case List(singleElem) => singleElem
    case sthElse => {
      val grouped = sthElse.grouped(2).toList
      val pairwiseOpd = for (g <- grouped) yield {
        g match {
          case List(a, b) => op(a, b)
          case List(x) => x
        }
      }
      nonassocPairwiseReduce(pairwiseOpd, op)
    }
  }
}

例如,如果这是您在String上的非关联操作:

def putInParentheses(a: String, b: String) = s"(${a} + ${b})"

然后举个例子

for {
  example <- List(
    ('1' to '6').toList.map(_.toString),
    ('a' to 'h').toList.map(_.toString)
  )
} {
  println(nonassocPairwiseReduce(example, putInParentheses))
}

已映射到

(((1 + 2) + (3 + 4)) + (5 + 6))
(((a + b) + (c + d)) + ((e + f) + (g + h)))

知道为什么要这样做很有趣。