2015-07-30 2 views
1

Я пытаюсь понять агрегат в Scala, и с одним примером я понял логику, но результат второй, которую я пытался смутить.понимание агрегата в Scala

Пожалуйста, дайте мне знать, где я ошибся.

Код:

val list1 = List("This", "is", "an", "example"); 

val b = list1.aggregate(1)(_ * _.length(), _ * _) 

1 * "Эта" .length = 4

1 * "является" .length = 2

1 * "AN" .length = 2

1 * "пример" .length = 7

4 * 2 = 8, 2 * 7 = 14

8 * 14 = 112

выход также пришел как 112. но ниже,

val c = list1.aggregate(1)(_ * _.length(), _ + _) 

Я думал, это будет выглядеть следующим образом. 4, 2, 2, 7

4 + 2 = 6

2 + 7 = 9

6 + 9 = 15,

но выход все же пришел, как 112.

Он идеально делать все операции я упоминал в seqop, здесь _ * _.length

Не могли бы вы объяснить, или кор выпрямите меня, где я ошибся.?

+0

См. Http://stackoverflow.com/questions/30828056/how-does-aggregate-work-in-scala/30828273 –

ответ

0

aggregate следует использовать для вычисления только ассоциативных и коммутативных операций. Давайте посмотрим на подпись функции:

def aggregate[B](z: ⇒ B)(seqop: (B, A) ⇒ B, combop: (B, B) ⇒ B): B 

B можно рассматривать как накопитель (и будет ваш выход). Вы даете начальное выходное значение, тогда первая функция заключается в том, как добавить значение A к этому аккумулятору, а второе - объединить 2 аккумулятора. Scala «выбирает» способ объединить вашу коллекцию, но если ваша агрегация не ассоциативна и не коммутативна, результат не является детерминированным, поскольку вопрос о заказе. Посмотрите на этот пример:

val l = List(1, 2, 3, 4) 
l.aggregate(0)(_ + _, _ * _) 

Если мы создаем один аккумулятор, а затем объединить все значения, которые мы получаем 1 + 2 + 3 + 4 = 10 но если мы решили распараллелить процесс путем разделения списка пополам мы могли бы (1 + 2) * (3 + 4) = 21.

Итак, что происходит на самом деле, так это то, что для List агрегат - это то же самое, что и foldLeft, что объясняет, почему изменение второй функции не меняло выход. Но где aggregate может быть полезным в Spark, например, или в других распределенных средах, где может быть полезно сделать сворачивание на каждом разделе независимо, а затем объединить результаты со второй функцией.

Смежные вопросы