zipWith (отображающийся по нескольким Seq) в Scala

Волшебство Мерзавца является всем, в чем Вы будете когда-либо нуждаться. Гарантируемый или Ваши деньги назад!

34
задан Mechanical snail 18 July 2012 в 01:05
поделиться

5 ответов

Нужная функция называется zipWith , но она не является частью стандартной библиотеки. Это будет в 2.8 (ОБНОВЛЕНИЕ: По-видимому, нет, см. Комментарии).

foo zipWith((f: Double, b : Double) => f+b) bar

См. этот билет Trac .

16
ответ дан 27 November 2019 в 16:02
поделиться

Ленивый список - это не копия списка - это больше похоже на отдельный объект. В случае реализации отложенного zip-архива каждый раз, когда запрашивается следующий элемент, он захватывает элемент из каждого из двух входных списков и создает из них кортеж, а затем вы разбиваете кортеж на части с сопоставлением с образцом в вашей лямбде.

Таким образом, нет необходимости создавать полную копию всего список (-ов) ввода перед началом работы с ними. Это сводится к очень похожему шаблону распределения для любого приложения, работающего на JVM - множество очень недолговечных, но небольших распределений, с которыми JVM оптимизирована для работы.

Обновление: для ясности, вам нужно использовать потоки (ленивые списки), а не списки. У потоков Scala есть zip, который работает лениво, поэтому вам не следует преобразовывать вещи в списки.

В идеале ваш алгоритм должен быть способен работать с двумя бесконечными потоками, не взрываясь (при условии, что это не выполняет сворачивания , конечно,

4
ответ дан 27 November 2019 в 16:02
поделиться

Что ж, отсутствие zip - это недостаток в Scala 2.7 Seq. Scala 2.8 имеет хорошо продуманную конструкцию коллекций, заменяющую случайный способ, которым коллекции, представленные в 2.7, появились (обратите внимание, что не все они были созданы одновременно с единым дизайном).

Теперь, когда вы Чтобы избежать создания временной коллекции, вам следует использовать «проекцию» в Scala 2.7 или «представление» в Scala 2.8. Это даст вам тип коллекции, для которого определенные инструкции, в частности map, flatMap и filter, не являются строгими. В Scala 2.7 проекцией списка является поток. В Scala 2.8 есть SequenceView для Sequence, но есть zipWith прямо там, в Sequence, он вам даже не понадобится.

Сказав, что, как уже упоминалось, JVM оптимизирована для обработки временного выделения объектов, а также, при работе в режиме сервера оптимизация времени выполнения может творить чудеса. Итак, не оптимизируйте преждевременно. Протестируйте код в условиях, в которых он будет запущен - и если вы не планировали запускать его в режиме сервера, подумайте еще раз, если ожидается, что код будет долгим, и выберите, когда / где / при необходимости.

РЕДАКТИРОВАТЬ

Что на самом деле будет доступно в Scala 2.8, так это:

(foo,bar).zipped.map(_+_)
10
ответ дан 27 November 2019 в 16:02
поделиться

ОБНОВЛЕНИЕ: Было указано (в комментариях), что этот «ответ» на самом деле не отвечает на задаваемый вопрос. Этот ответ будет отображаться для каждой комбинации из foo и bar , создавая элементы N x M вместо min ( M, N) по запросу. Итак, это неверно , но оставлено для потомков, поскольку это хорошая информация.


Лучший способ сделать это - использовать flatMap в сочетании с map . Код говорит громче, чем слова:

foo flatMap { f => bar map { b => f + b } }

В результате будет получен один Seq [Double] , как и следовало ожидать. Этот шаблон настолько распространен, что Scala фактически включает некоторую синтаксическую магию, которая его реализует:

for {
  f <- foo
  b <- bar
} yield f + b

Или, альтернативно:

for (f <- foo; b <- bar) yield f + b

for {... } Синтаксис - действительно самый идиоматический способ сделать это. Вы можете продолжить добавлять условия генератора (например, b <- bar ) по мере необходимости. Таким образом, если внезапно получается три Seq , которые вы должны сопоставить, вы можете легко масштабировать свой синтаксис вместе с вашими требованиями (для создания фразы).

1
ответ дан 27 November 2019 в 16:02
поделиться

В Scala 2.8:

val baz = (foo, bar).zipped map (_ + _)

И работает более чем с двумя операндами одинаково. Т.е. затем вы можете продолжить это с помощью:

(foo, bar, baz).zipped map (_ * _ * _)
82
ответ дан 27 November 2019 в 16:02
поделиться
Другие вопросы по тегам:

Похожие вопросы: