spark scala reduce fold

scala - foldleft spark



Scala: fold vs foldLeft (1)

Estoy tratando de entender cómo doblar y doblar hacia la izquierda y el respectivo reducir y reducir el trabajo izquierdo. Usé fold y foldLeft como mi ejemplo

scala> val r = List((ArrayBuffer(1, 2, 3, 4),10)) scala> r.foldLeft(ArrayBuffer(1,2,4,5))((x,y) => x -- y._1) scala> res28: scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer(5) scala> r.fold(ArrayBuffer(1,2,4,5))((x,y) => x -- y._1) <console>:11: error: value _1 is not a member of Serializable with Equals r.fold(ArrayBuffer(1,2,4,5))((x,y) => x -- y._1)

¿Por qué fold no funcionó como foldLeft ? ¿Qué es Serializable with Equals ? Entiendo fold y foldLeft tiene una ligera firma de API diferente en términos de tipos genéricos de parámetros. Por favor avise. Gracias.


El fold método (originalmente agregado para el cálculo en paralelo) es menos poderoso que foldLeft en términos de tipos a los que se puede aplicar. Su firma es:

def fold[A1 >: A](z: A1)(op: (A1, A1) => A1): A1

Esto significa que el tipo sobre el que se realiza el plegado debe ser un supertipo del tipo de elemento de colección.

def foldLeft[B](z: B)(op: (B, A) => B): B

La razón es que fold puede implementarse en paralelo, mientras que foldLeft no puede. Esto no solo se debe a la *Left parte *Left que implica que foldLeft va de izquierda a derecha secuencialmente, sino también porque el operador op no puede combinar resultados calculados en paralelo; solo define cómo combinar la agregación tipo B con el elemento tipo A , pero no cómo combinar dos agregaciones de tipo B El método de fold , a su vez, define esto, porque el tipo de agregación A1 tiene que ser un supertipo del elemento tipo A , que es A1 >: A Esta relación de supertipo permite al mismo tiempo doblar la agregación y los elementos, y combinar agregaciones, ambas con un solo operador.

Pero esta relación de supertipo entre la agregación y el tipo de elemento también significa que el tipo de agregación A1 en su ejemplo debe ser el supertipo de (ArrayBuffer[Int], Int) . Dado que el elemento cero de su agregación es ArrayBuffer(1, 2, 4, 5) del tipo ArrayBuffer[Int] , se deduce que el tipo de agregación es el supertipo de ambos, y que es Serializable with Equals , el único menos límite superior de una tupla y un buffer de matriz.

En general, si desea permitir el plegado en paralelo para tipos arbitrarios (que se hace fuera de servicio), debe usar el aggregate método aggregate que requiere definir cómo se combinan dos agregaciones. En tu caso:

r.aggregate(ArrayBuffer(1, 2, 4, 5))({ (x, y) => x -- y._1 }, (x, y) => x intersect y)

Por cierto, intente escribir su ejemplo con reduce / reduceLeft : debido a la relación de supertipo entre el tipo de elemento y el tipo de agregación que ambos métodos tienen, descubrirá que genera un error similar al que ha descrito.