2012-09-26 18 views

risposta

41

L'elenco ha il metodo di appiattimento. Perché non usarlo?

List(List(1,2), List(3,4)).flatten 
> List(1,2,3,4) 
+1

Come pensate di appiattire questa 'List (1, Lista (2,3), 4, Lista (5,6,7))' attesi il risultato è 'Elenco (1, 2, 3, 4, 5,6,7)' –

+2

l'elenco sopra riportato è eterogeneo, l'appiattimento non funzionerà lì. Puoi fare qualcosa come: Lista (1, Lista (2,3), 4, Lista (5,6,7)). Collect {case i: Int => List (i); case l @ a :: b => l} .flatten – Jan

10

Dato l'esempio precedente, non sono sicuro che sia necessario ricorrere. Sembra che tu voglia List.flatten invece.

ad es.

scala> List(1,2,3) 
res0: List[Int] = List(1, 2, 3) 

scala> List(4,5,6) 
res1: List[Int] = List(4, 5, 6) 

scala> List(res0,res1) 
res2: List[List[Int]] = List(List(1, 2, 3), List(4, 5, 6)) 

scala> res2.flatten 
res3: List[Int] = List(1, 2, 3, 4, 5, 6) 
10

.flatten è ovviamente il modo più semplice, ma per completezza si dovrebbe anche sapere su flatMap

val l = List(List(1, 2), List(3, 4)) 
println(l.flatMap(identity)) 

e la for-comprensione equivalente

println(for (list <- l; x <- list) yield x) 

appiattire è ovviamente un caso speciale di flatMap, che può fare molto di più.

+0

Se si desidera aggiungere alcuni dati durante la mappa, questo è ciò che si desidera. –

0

Non hai bisogno di ricorsione, ma è possibile utilizzarlo se si vuole:

def flatten[A](list: List[List[A]]):List[A] = 
    if (list.length==0) List[A]() 
    else list.head ++ flatten(list.tail) 

Questo funziona come metodo di appiattire costruire in lista. Esempio:

scala> flatten(List(List(1,2), List(3,4))) 
res0: List[Int] = List(1, 2, 3, 4) 
0

Se la struttura può essere ulteriormente annidati, come:

List(List(1, 2, 3, 4, List(5, 6, List(7, 8)))) 

Questa funzione dovrebbe darvi il risultato desiderio:

def f[U](l: List[U]): List[U] = l match { 
    case Nil => Nil 
    case (x: List[U]) :: tail => f(x) ::: f(tail) 
    case x :: tail => x :: f(tail) 
} 
0

Se si desidera utilizzare flatmap, qui è la via

Supponiamo di avere una lista di lista [Int] di nome ll, e di appiattirla in lista, molte persone già ti danno le risposte, come ad esempio appiattito, questo è il modo semplice. Presumo che tu stia chiedendo di usare il metodo flatmap. Se è il caso, qui è il modo

ll.flatMap(_.map(o=>o)) 
+0

In che modo questa risposta è diversa dalla risposta data da Dave Griffith 5 anni fa?(Oltre al fatto che la risposta più vecchia è più pulita e concisa.) – jwvh

+0

Hai ragione, quasi la stessa cosa. Credo che il mio sia più facile da capire o darti qualche colpo per la sottolineatura. Sto passando una funzione di identità invece di una parola chiave di identità. Spero che abbia senso per te – Robin