Frage

Ich weiß, dass Scala Listen haben eine Umsetzung mit Unterschrift (f: (A) => B):List[B] und foreach Umsetzung mit Unterschrift (f: (A) => Unit):Unit aber ich bin auf der Suche nach etwas, das mehrere Iterables die gleiche Art und Weise, dass der Python map akzeptiert mehrere Iterables.

Ich bin auf der Suche nach etwas mit einer Signatur von (f: (A,B) => C, Iterable[A], Iterable[B] ):Iterable[C] oder gleichwertig. Gibt es eine Bibliothek, wo diese vorhanden ist oder eine vergleichbare Art und Weise zu tun, ähnlich?

Edit:

Wie vorgeschlagen unten ich tun konnte,

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

, aber das erzeugt eine temporäre Liste in zwischen den Schritten. Wenn der Kommentator würde schreiben kann ich upvote ihn (Hinweis, Tip), aber ist es eine andere Möglichkeit?

War es hilfreich?

Lösung

In scala 2.8 gibt es ein Verfahren, bei Tuple2 & Tuple3 genannt Reißverschluss, die vermeiden temporäre Sammlung zu erstellen. Hier einige Beispiel-Anwendungsfall:

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>

Es ist eine ZIP-Methode in beiden Tuple2 und Tuple3. xs.zip (ys) ist das gleiche wie (xs, ys) .zip

Hinweis: Es gibt auch einigen Mangel in (xs, ys) .zip und (xs, ys) .zipped, stellen Sie sicher, dass xs kein unendlicher Strom sein kann. Zum Ticket # 2634 für weitere Informationen. Ich habe ein Post in nabble.com vor einigen Tagen, die zeigen, meine Meinung darüber, wie dieses Ticket zu beheben.

Andere Tipps

Die Funktion, die Sie suchen ist in der Regel zipWith genannt. Es ist leider nicht in den Standardbibliotheken zur Verfügung gestellt, aber es ist ziemlich einfach zu schreiben:

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
  }

Dies wird nur einmal durchlaufen, da die Implementierungen für zip und map auf Iteratoren voll faul sind.

Aber warum Anschlag am Iterable? Dies hat eine noch allgemeinere Form. Wir könnten eine Schnittstelle für alle Datenstrukturen erklären, dass auf diese Weise gezippt werden können.

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

Zum Beispiel können wir Funktionen 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))
}

Es stellt sich heraus, ein noch allgemeiner Ausdruck dieser Art zu sein. Im Allgemeinen Typkonstruktoren, die eine Implementierung dieser Schnittstelle sind applicative functors

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]
}

Eine Implementierung von zipWith ist dann nur dies:

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)

Diese generalisiert auf Funktionen jeder Stelligkeit:

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

Die Scalaz Bibliothek bietet Applicative Instanzen für eine Vielzahl von Datenstrukturen in der Standardbibliothek . Auch praktische Syntax für ap zur Verfügung gestellt. In Scalaz wird diese Funktion <*> genannt:

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

Es gibt ein Verfahren map2 im List Objekt in Scala 2.7 (und 2.8, aber es ist für zipped veraltet). Sie verwenden es, etwa so:

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

Eastsun ist bereits gezeigt, wie zipped in 2.8 verwenden (die auf allen Sammlungen funktioniert, nicht nur Listen).

Nun, ich weiß nicht weiß die Syntax (f: (A,B) => C, Iterable[A], Iterable[B] ):Iterable[C] (und ich weiß, nichts von Scala), aber wenn ich raten müsste, wäre es „eine Funktion bedeuten < em> f nehmen zwei iterable Argumente A und B und Rückkehr ein iterable C “. Ich bin mir nicht sicher, ob dies bedeutet, dass alle Iterables die gleiche Anzahl von Elementen ergeben.

In Python, ich glaube, Sie suchen die zip Funktion :

>>> 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 der Ausgang ist immer nur so lang wie die kürzeste iterable:

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

Wie auch immer, einige integrierten Python-Funktionen alle Bedürfnisse zu kennen, aber leicht verfehlt: enumerate, map, reduce und zip. filter verwendet auf dieser Liste zu sein, aber es ist klarer und flexibler eine Liste Verständnis in diesen Tagen zu verwenden.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top