2010-04-08 14 views

Odpowiedz

7

W 2,8, którą prawdopodobnie użyć metody:

scala> val a = "ABCDEF".toList.map(_.toString) 
a: List[java.lang.String] = List(A, B, C, D, E, F) 

scala> a.grouped(2).partialMap{ case List(a,b) => (a,b) }.toList 
res0: List[(java.lang.String, java.lang.String)] = List((A,B), (C,D), (E,F)) 

(to 2.8.0 Beta1; najnowszy bagażnik ma collect zamiast partialMap.)

W 2,7 - a nie złe runner-up w 2,8 - można utworzyć metody rekurencyjnej jako legoscia zrobił:

def zipPairs[A](la : List[A]): List[(A,A)] = la match { 
    case a :: b :: rest => (a,b) :: zipPairs(rest) 
    case _ => Nil 
} 

scala> zipPairs(a) 
res1: List[(java.lang.String, java.lang.String)] = List((A,B), (C,D), (E,F)) 

Edit: oto kolejny podejście briefer który działa na 2,7 także:

scala> (a zip a.drop(1)).zipWithIndex.filter(_._2 % 2 == 0).map(_._1) 
res2: List[(java.lang.String, java.lang.String)] = List((A,B), (C,D), (E,F)) 

(Uwaga wykorzystania drop(1) zamiast tail więc działa z pustymi listami.)

4

Nietestowane:

def ziptwo(l: List[String]): List[(String, String)] = l match { 
    case Nil => Nil 
    case a :: b :: rest => 
     Pair(a,b) :: ziptwo(rest) 
} 
+2

nie będzie działał przez długi wykazach nie ogon rekurencyjnej. –

4

w Scala 2.8 można zrobić:

def pairs[T](xs: List[T]) = 
    xs.grouped(2) 
    .map{case List(a, b) => (a,b)} 
    .toList 
+0

Shucks, pokonaj mnie 34 sekundy! :) Ale chcesz 'partialMap' /' collect', albo wygeneruje wyjątek na listach o nieparzystej długości. –

+3

Możesz nazwać ten błąd lub funkcję :-) –

1
def pairify[T](list: List[T]): List[(T, T)] = list match { 
    case Nil => Nil 
    case x :: y :: xs => (x, y) :: pairify(xs) 
    case _ => error("odd length list!") 
} 
3

jedyną zaletą h Każdy, kto wymyśli najbardziej oczywiste sposoby zrobienia tego, musi bardziej się zastanowić nad alternatywnymi rozwiązaniami. A więc jest taki, który działa na Scali 2.8. Na Scala 2.7, zamień view na projection.

def everyNofM[T](l: List[T], n: Int, m: Int) = 
    l.view.zipWithIndex.filter(_._2 % m == n).map(_._1) 
def evens[T](l: List[T]) = everyNofM(l, 0, 2) 
def odds[T](l: List[T]) = everyNofM(l, 1, 2) 
def zip[T](l: List[T]) = evens(l) zip odds(l) toList 

Ściśle mówiąc, view/projection nie jest konieczne, ale unika się niepotrzebnego utworzenie pośrednich wyników.

Inne sposoby zabawy robi to:

def zip[T](l: List[T]) = l.indices.partition(_ % 2 == 0).zipped.map(
    (x: Int, y: Int) => (l(x), l(y)) 
).toList 

def zip[T](l: List[T]) = l.zipWithIndex.partition(_._2 % 2 == 0).zipped.map(
    (x, y) => (x._1, y._1) 
) 

PS: punkt bonusowy aby ktokolwiek dostaje słów. ;-)

+1

+1, ścisły? [15-wypełniacz] – missingfaktor

1

Pozwala to niepełne pary:

def pairwise [T] (xs: List[T]) : List [(Option[T], Option[T])] = xs match { 
    case (x :: y :: xsr) => (Some (x), Some (y)) :: pairwise (xsr)    
    case (x :: Nil) => List ((Some (x), None))         
    case (_) => Nil } 
+1

Myślę, że "Para" z 'Opcji' jest złym wyborem. Co powiesz na "List [Albo [Pair [T, T], Tuple1 [T]]]" zamiast? –

+0

Dlaczego para opcji jest złym wyborem? Ponieważ możesz dostać parę par? Tak, to nie jest ładne, ale przechowujesz informacje, skąd pochodzi element: [kod] Lista ((Alicia, Nowy Meksyk), (Stefan, Berlin), (Paryż)) // Paris Hilton lub Paris/Francja? Lista ((Alicia, Nowy Meksyk), (Stefan, Berlin), (Brak, Paryż)) Lista ((Alicia, Nowy Meksyk), (Stefan, Berlin), (Paryż, brak)) [/ code] W drugim przykładzie brak informacji. –

Powiązane problemy