2016-07-02 5 views
2

Я родом из R-фона, поэтому я привык использовать семейство функций R *.Scala эквивалент R's Mapply?

Функции Scala's list.foreach(_.fun) и list.map(_.fun) очень похожи на функции R lapply(list, fun), поскольку они итеративно выполняют функцию над каждым элементом списка.

Однако R также имеет функцию mapply(fun, list1, list2, ...), что полезно, если у вас есть несколько списков и вы хотите применить функцию по первому элементу каждого, по второму элементу каждого и так далее. Например, если бы у меня была функция add(x, y, z) и два списка x=(1, 2, 3), y=(2, 3, 4) и z=(3, 4, 5), mapply(add, x, y, z) вернули (6, 9, 12).

Имеет ли Scala какой-либо эквивалент R's mapply, без использования петли?

+0

Может кто-нибудь объяснить, почему этот вопрос был отклонен? Я задаю вопрос программирования, который был нелегким для Google и, похоже, не дублировал его в Stack Overflow. Ликвидация без комментариев не способствует сообществу. – Shuklaswag

+0

Я не уменьшал вас, однако, так как мне также не нравятся downvotes без комментариев, и у меня достаточно репутации, чтобы понять, почему люди голосуют, чтобы закрыть свой пост, я могу вам сказать. Они указывают на правило, в котором говорится: «Вопросы, предлагающие нам рекомендовать или находить книгу, инструмент, библиотеку программного обеспечения, учебник или другой ресурс вне сайта, не соответствуют теме« Переполнение стека », поскольку они склонны привлекать упрямые ответы и спам. описать проблему и то, что было сделано до сих пор, для ее решения » –

+0

Как насчет этого: https://dahl.byu.edu/software/rscala/rscala-jss.pdf. Вы можете просто использовать «mapply» в Scala! –

ответ

2

Там нет аналогичного рутина в стандартной библиотеке, но вы можете получить близко:

scala> List(List(1,2,3),List(5,6,7),List(14,13,12)).transpose 
res3: List[List[Int]] = List(List(1, 5, 14), List(2, 6, 13), List(3, 7, 12)) 

scala> List(List(1,2,3),List(5,6,7),List(14,13,12)).transpose.map(_.sum) 
res4: List[Int] = List(20, 21, 22) 

Примечание: transpose требует, чтобы все суб-коллекции имеют одинаковый размер.


Followup на ваш комментарий.

Я не уверен, что вы понимаете, что такое zipped. Он преобразует 2 подкатегории внутри кортежа (Tuple2) в единый набор кортежей, каждый из которых затем может быть присвоен функции, которая принимает 2 параметра данных типов. Это также доступно для 3 подкатегорий, внутри Tuple3, став коллекцией троек, но это предел.

Кроме того, я не знаю, почему вы думаете: «zipped - это один вызов функции, а не два». Если вы следуете link Ричарду Скривену, предложенному в его комментарии, и сравните два предлагаемых решения, вы увидите, что они имеют одинаковое количество шагов/операторов.

Как я это вижу, разбивка преимущества/недостатки следующим образом:

  • Если вы имеете дело с коллекциями разных типов, скажем Seq[Int] и Seq[Char], то вы хотите, чтобы получить их zipped перед нанесением функция «объединитель»: f(i1,c1), затем f(i2,c2), затем f(i3,c3) и т. д.
  • Ни один из подходов не подходит для подкатегорий разных размеров. transpose будет генерировать исключение, а zipped просто игнорирует все элементы за максимальным индексом наименьшей подсекции.
  • Если ваша функция «сумматор» принимает более трех аргументов, вы не можете использовать zipped.
  • Если ваш «объединитель» берет коллекцию в качестве входных данных, то transpose, вероятно, лучший вариант.
+0

Умное решение! Знаете ли вы, что это решение лучше, чем использование 'zipped'? Конечный результат кажется таким же, за исключением того, что 'zipped' является одним вызовом функции, а не двумя. – Shuklaswag

+0

Моя оценка 'zipped' была добавлена ​​к предлагаемому ответу. – jwvh