Desidero copiare in modo superficiale un elenco in Scala.Come copiare un elenco in Scala
ho voluto fare somehing come:
val myList = List("foo", "bar")
val myListCopy = myList.clone
Ma il metodo clone è protetto.
Desidero copiare in modo superficiale un elenco in Scala.Come copiare un elenco in Scala
ho voluto fare somehing come:
val myList = List("foo", "bar")
val myListCopy = myList.clone
Ma il metodo clone è protetto.
per filtrare un elenco:
val list = List(1,2,3,4,5)
//only evens
val evens = list.filter(e=>e%2 == 0)
println(list)
//--> List(1, 2, 3, 4, 5)
println(evens)
//--> List(2, 4)
è anche possibile utilizzare il carattere jolly per salvare alcuni personaggi:
val evens = list.filter(_%2==0)
Si noti che, come commentato in precedenza, le liste sono immutabili. Ciò significa che queste operazioni non modificano l'elenco originale, ma in realtà creano un nuovo elenco.
Ecco una non risposta: non farlo. Un List
è immutabile, quindi non ha assolutamente senso copiarne uno.
Prendiamo in considerazione un paio di operazioni:
val list = List(1,2,3)
val l1 = 0 :: list
val l2 = "a" :: list
Né l1
né l2
stanno alterando list
, ma entrambi creare nuove liste che fanno riferimento a list
.
Spieghiamo questo in dettaglio. Il costruttore List(1,2,3)
sta creando tre elementi e utilizza anche un oggetto singleton. In particolare, si istanziare questi elementi:
::(3, Nil)
::(2, reference to the previous element)
::(1, reference to the previous element)
E Nil
è un oggetto singoletto. Ciò a cui l'identificatore list
punta effettivamente è l'ultimo elemento.
Ora, quando si assegnano 0 :: list
-l1
, si sta istanziare un nuovo oggetto:
::(0, reference to ::(1, etc))
Naturalmente, dato che c'è un riferimento a list
, si può pensare di l1
come una lista di quattro elementi (o cinque, se contate Nil
).
Ora l2
non è nemmeno dello stesso tipo di list
, ma lo fa anche ANCHE! Qui:
::("a", reference to ::(1, etc))
Il punto importante di tutti questi oggetti, però, è che essi non possono essere cambiati. Non ci sono setter, né alcun metodo che cambierà nessuna delle loro proprietà. Avranno sempre gli stessi valori/riferimenti nella loro "testa" (questo è ciò che chiamiamo il primo elemento) e gli stessi riferimenti nella loro "coda" (questo è ciò che chiamiamo il secondo elemento).
Tuttavia, ci sono metodi che sembrano come se stessero cambiando la lista. State certi, tuttavia, che stanno creando nuovi elenchi.Per esempio:
val l3 = list map (n => n + 1)
La mappa metodo crea una nuova lista, delle stesse dimensioni, in cui elemento nuovo può essere calcolata da un elemento corrispondente nella list
(ma si potrebbe ignorare il vecchio elemento pure).
val l4 = l2 filter (n => n.isInstanceOf[Int])
Mentre l4
ha gli stessi elementi list
(ma un tipo diverso), è anche un nuovo elenco. Il metodo filter
crea un nuovo elenco, basato su una regola che si passa per dirgli quali elementi vanno e quali no. Non tenta di ottimizzare nel caso in cui potrebbe restituire un elenco esistente.
val l5 = list.tail
Questo non crea un nuovo elenco. Invece, assegna semplicemente a l5
un elemento esistente di list
.
val l6 = list drop 2
Ancora nessuna nuova lista creata.
val l7 = list take 1
Questo, tuttavia, crea un nuovo elenco, proprio perché non può cambiare il primo elemento di list
in modo che i suoi punti di coda a Nil
.
Ecco alcuni ulteriori dettagli di implementazione:
List
è una classe astratta. Ha due discendenti, la classe ::
(sì, questo è il nome della classe) e l'oggetto singleton Nil
. List
è sigillato, quindi non è possibile aggiungere nuove sottoclassi e ::
è definitivo, quindi non è possibile creare una sottoclasse.
Mentre non è possibile fare nulla per modificare un elenco, utilizza lo stato mutabile internamente in alcune operazioni. Questo aiuta con le prestazioni, ma è localizzato in modo che nessun programma che scrivi possa mai rilevarlo o subire conseguenze da esso. Puoi passare gli elenchi come preferisci, indipendentemente dalle funzioni che le altre funzioni fanno con loro o da quanti thread li stanno utilizzando contemporaneamente.
Non sarebbe legato alla http://stackoverflow.com/questions/1267261/does-scala-anyref-clone-perform-a-shallow-or-deep-copy? – VonC
Per cosa? Gli oggetti elenco sono immutabili. –
Volevo rimuovere un elemento dall'elenco (utilizzando il metodo remove (A => Boolean)) in un ciclo. (Nota: ho avviato Scala 2 ore fa :)) – Maxime