2010-04-08 20 views

Respuesta

7

En 2,8, lo que probablemente utilizar métodos:

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)) 

(Esto es 2.8.0 Beta1; el último tronco tiene collect en lugar de partialMap.)

En 2.7 - y no un mal segundo en 2,8 - que podría crear un método recursivo como lo hizo legoscia:

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)) 

Editar: aquí hay otro enfoque más breve que funciona en 2.7 también:

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)) 

(Observe el uso de drop(1) en lugar de tail por lo que funciona con listas vacías.)

4

No comprobado:

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

Esto no funcionará para las listas largas, ya que no es recursiva cola. –

4

en Scala 2.8 que puede hacer:

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

¡Shucks, vencerme por 34 segundos! :) Sin embargo, querrás 'partialMap' /' collect', o arrojará una excepción en las listas de longitud impar. –

+3

Podría llamar a eso un error, o una característica :-) –

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

la única ventaja de h Después de que todos descubran las formas más obvias de hacerlo es que tengo que pensar más en las soluciones alternativas. Así que aquí hay uno que funciona en Scala 2.8. En Scala 2.7, reemplace view con 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 

en sentido estricto, view/projection es innecesario, sino que evita la creación innecesaria de los resultados intermedios.

Otras formas divertidas de hacerlo:

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: punto de bonificación para el que llegue el juego de palabras. ;-)

+1

+1, ¿Estricto? [Cargador de 15 carbonos] – missingfaktor

1

Esto permite pares incompletas:

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

Creo que un 'Pair' of' Option' es una mala elección. ¿Qué tal una 'Lista [O bien [Emparejar [T, T], Tuple1 [T]]] en su lugar? –

+0

¿Por qué es un par de opciones una mala opción? Porque puede obtener un par de Nones? Sí, eso no es bonito, pero conserva la información de donde proviene un elemento: [código] Lista ((Alicia, Nuevo México), (Stefan, Berlín), (París)) // Paris Hilton o París/¿Francia? Lista ((Alicia, Nuevo México), (Stefan, Berlín), (Ninguna, París)) Lista ((Alicia, Nuevo México), (Stefan, Berlín), (París, Ninguno)) [/ code] En el segundo ejemplo, no se pierde información. –

Cuestiones relacionadas