문제

Is there a standard way of combining existing Scala collection functions to achieve the following? Or is this already defined in some popular extension library like Scalaz?

def partialReduceLeft[T](elements: List[T], nextReduction: List[T] => (T, List[T])): List[T] =
  if (elements == Nil)
    Nil
  else {
    val (reduction, residual) = nextReduction(elements)

    if (residual.length >= elements.length)
      throw new Exception("Residual collection from nextReduction function must be smaller than its input collection.")

    if (residual == Nil)
      List(reduction)
    else
      reduction :: partialReduceLeft(residual, nextReduction)
  }

The function takes a collection and applies a user-defined function which returns the first reduction, which may consume one or more elements. The method keeps going until all elements are consumed.

The resulting collection may have an equal or lower size to the input collection (I rather unscientifically call this a 'partial reduce left' - for want of knowing the exact term for this type of standard function :)).

My implementation is not tail-recursive, and to be honest, I'd much rather use someone else's code!!

도움이 되었습니까?

해결책

There is similar method in scalaz: unfold.

You could implement your method using unfold this way:

def partialReduceLeft[T](elements: List[T],
                         nextReduction: List[T] => (T, List[T])): Stream[T] =
  unfold(elements){ es => es.nonEmpty option nextReduction(es) }
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top