Есть ли эквивалент в Scala к большей общей функции карты Python?

StackOverflow https://stackoverflow.com/questions/2650156

Вопрос

Я знаю, что списки Scala имеют карта Реализация с подписью (f: (A) => B):List[B] и а для каждого Реализация с подписью (f: (A) => Unit):Unit Но я ищу что-то, что принимает несколько повторных документов так же, как Python карта принимает несколько повторных документов.

Я ищу что-то с подписью (f: (A,B) => C, Iterable[A], Iterable[B] ):Iterable[C] или эквивалент. Есть ли библиотека, где это существует или сопоставимый способ сделать подобное?

Редактировать:

Как предложено ниже, я мог бы сделать

val output = myList zip( otherList ) map( x => x(0) + x(1) )

Но это создает временный список между шагами. Если комментатор будет опубликовать, я мог бы расширить его (намек, намек), но есть ли другой способ?

Это было полезно?

Решение

В Scala 2.8 есть метод, называемый Zainted в Tuple2 & Tuple3, которые избегают создания временного сбора. Вот некоторое образец применения корпуса:

Welcome to Scala version 2.8.0.r21561-b20100414020114 (Java HotSpot(TM) Client VM, Java 1.6.0_18).
Type in expressions to have them evaluated.
Type :help for more information.

scala> val xs = 0 to 9
xs: scala.collection.immutable.Range.Inclusive with scala.collection.immutable.Range.ByOne = Range(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)

scala> val ys = List.range(0,10)
ys: List[Int] = List(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)

scala> val zs = Array.range(0,10)
zs: Array[Int] = Array(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)

scala> (xs,ys).zipped.map{ _+_ }
res1: scala.collection.immutable.IndexedSeq[Int] = Vector(0, 2, 4, 6, 8, 10, 12, 14, 16, 18)

scala> (zs,ys,xs).zipped.map{ _+_+_ }
res2: Array[Int] = Array(0, 3, 6, 9, 12, 15, 18, 21, 24, 27)

scala>

Существует ZIP-метод в Tuple2 и Tuple3. xs.zip (ys) такой же, как (XS, YS) .zip

Примечание: Существует также некоторая нехватка в (XS, YS) .zip и (xs, ys) .ziped, убедитесь, что XS не может быть бесконечным потоком. Идти к Билет # 2634. Чтобы получить больше информации. у меня есть Почта В nabble.com несколько дней назад, которое показывает мое мнение о том, как исправить этот билет.

Другие советы

Функция, которую вы ищете, обычно называется zipWith. Отказ К сожалению, не предусмотрено в стандартных библиотеках, но это довольно легко написать:

def zipWith[A,B,C](f: (A,B) => C, a: Iterable[A], b: Iterable[B]) =
  new Iterable[C] {
    def elements = (a.elements zip b.elements) map f.tupled
  }

Это пройдет только один раз, поскольку реализации для zip а также map На итераторы полностью ленивы.

Но зачем останавливаться в Iterable? Это имеет еще более общую форму. Мы могли бы объявить интерфейс для всех структур данных, которые могут быть запущены таким образом.

trait Zip[F[_]] {
  def zipWith[A,B,C](f: (A,B) => C, a: F[A], b: F[B]): F[C]
}

Например, мы можем zip-функции:

trait Reader[A] {
  type Read[B] = (A => B)
}

def readerZip[T] = new Zip[Reader[T]#Read] {
  def zipWith[A,B,C](f: (A,B) => C, a: T => A, b: T => B): T => C =
    (t: T) => f(a(t),b(t))
}

Оказывается еще более общее выражение этого типа. В целом, введите конструкторы, которые позволяют реализацию этого интерфейса Применяющие функторы

trait Applicative[F[_]] {
  def pure[A](a: A): F[A]
  def map[A,B](f: A => B, a: F[A]): F[B]
  def ap[A,B](f: F[A => B], a: F[A]): F[B]
}

Реализация Zipwith тогда только это:

def zipWith[F[_],A,B,C](f: A => B => C, a: F[A], b: F[B])
                       (implicit m: Applicative[F]) =
  m.ap(m.map(f,a), b)

Это обобщает функции любой артерии:

  m.ap(m.ap(m.ap(m.map(f,a), b), c), d)

То Касляз Библиотека предоставляет примеры для многих структур данных в стандартной библиотеке. Также предоставляется удобный синтаксис для ap. Отказ В Scalaz эта функция называется <*>:

def zipWith[F[_]:Applicative,A,B,C](f: A => B => C, a: F[A], b: F[B]) =
  (a map f) <*> b

Есть метод map2 в List объект в Scala 2.7 (и 2.8, но он устарел в пользу zipped). Вы используете это так:

List.map2( List(1,2,3) , List(4,5,6) ) { _ * _ }  // Gives List(4,10,18)

Истсун уже показал, как использовать zipped В 2.8 (который работает на всех коллекциях, а не только в списках).

Ну, я не знать синтаксис (f: (A,B) => C, Iterable[A], Iterable[B] ):Iterable[C] (и я знаю ничего Scala), но если бы я должен был догадаться, это будет означать "функцию F. принимать два намерения А. а также Преступность и возвращение потенциала Слияние«Я не уверен, что это подразумевает, что все возможности дают одинаковое количество предметов.

В питоне, я думаю, вы ищете zip. Функция:

>>> A = range(10, 15)
>>> B = range(1000, 1500, 100)
>>> zip(A, B)
[(10, 1000), (11, 1100), (12, 1200), (13, 1300), (14, 1400)]
>>> [a + b for a,b in zip(A, B)]
[1010, 1111, 1212, 1313, 1414]

zipВыход до тех пор, пока самый короткий намекет:

>>> A=range(10, 12)
>>> zip(A, B)
[(10, 1000), (11, 1100)]

В любом случае, некоторые встроенные функции Python каждый должен знать, но легко пропускает: enumerate, map, reduce, а также zip. filter Используется для этого списка, но ясный и более гибкий для использования списка в наши дни.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top