web-dev-qa-db-fra.com

Ajouter un élément à une liste In Scala

J'utilise Scala 2.10.2. Je veux créer une liste, puis ajouter des éléments à la liste et m'attendre à voir tous les éléments de la liste lorsque j'appelle le nom de la liste. Mais J'ai observé quelque chose d'assez étrange (du moins bizarre pour moi depuis que je suis un débutant). Voici ce que j'ai essayé de faire dans mon sbt console

scala> val l = 1.0 :: 5.5 :: Nil
l: List[Double] = List(1.0, 5.5)

scala> l
res0: List[Double] = List(1.0, 5.5)

scala> l ::: List(2.2, 3.7)
res1: List[Double] = List(1.0, 5.5, 2.2, 3.7)

scala> List(l) :+ 2.2
res2: List[Any] = List(List(1.0, 5.5), 2.2)

scala> l
res3: List[Double] = List(1.0, 5.5)

scala> 

Tout d'abord, j'ai créé la liste l avec 2 éléments (1.0 et 5.5). J'appelle l et j'obtiens ce que j'attends. les deux éléments. Maintenant, j'ai essayé d'ajouter un autre élément à la liste en utilisant ::: qui a renvoyé une nouvelle liste avec une nouvelle liste d’éléments que j’ai ajoutés (2.2 et 3.7) Sweet! J'ai même vérifié l'aide du code de quelqu'un d'autre: Ajout d'un élément à la fin d'une liste dans Scala pour utiliser une nouvelle construction :+. Donc à ce stade, je suis tout content, mais j'appelle l et j'obtiens l'inattendu: `res3: List [Double] = List (1.0, 5.5) '.

Où sont les éléments que j'ai ajoutés? Et comment puis-je ajouter ces éléments correctement pour que lorsque j'appelle l, je reçoive une nouvelle liste avec tout ce que j'ai ajouté?

34
Emmanuel

Vous utilisez une liste immuable. Les opérations sur la liste renvoient une nouvelle liste. L'ancienne liste reste inchangée. Cela peut être très utile si une autre classe/méthode contient une référence à la collection originale et s’appuie sur elle pour qu’elle reste inchangée. Vous pouvez utiliser différents noms nommés comme dans

val myList1 = 1.0 :: 5.5 :: Nil 
val myList2 = 2.2 :: 3.7 :: mylist1

ou utilisez un var comme dans

var myList = 1.0 :: 5.5 :: Nil 
myList :::= List(2.2, 3.7)

C'est la syntaxe équivalente pour:

myList = myList.:::(List(2.2, 3.7))

Ou vous pouvez utiliser l’une des collections mutables telles que

val myList = scala.collection.mutable.MutableList(1.0, 5.5)
myList.++=(List(2.2, 3.7))

À ne pas confondre avec ce qui suit, qui ne modifie pas la liste mutable d'origine, mais renvoie une nouvelle valeur:

myList.++:(List(2.2, 3.7))

Cependant, vous ne devez utiliser que des collections mutables dans le code critique de performance. Les collections immuables sont beaucoup plus faciles à raisonner et à utiliser. Un gros avantage est que la liste immuable et scala.collection.immutable.Vector sont Covariant. Ne vous inquiétez pas si cela ne vous dit rien pour le moment. L'avantage est que vous pouvez l'utiliser sans le comprendre parfaitement. Par conséquent, la collection que vous utilisiez par défaut est en réalité scala.collection.immutable.List elle vient d’être importée automatiquement pour vous.

J'ai tendance à utiliser List comme ma collection par défaut. À partir de 2.12.6, la valeur par défaut est Seq immuable avant, la valeur par défaut est immuable.

44
Rich Oliver

Utilisez import scala.collection.mutable.MutableList ou similaire si vous avez vraiment besoin d'une mutation.

import scala.collection.mutable.MutableList
val x = MutableList(1, 2, 3, 4, 5)
x += 6 // MutableList(1, 2, 3, 4, 5, 6)
x ++= MutableList(7, 8, 9) // MutableList(1, 2, 3, 4, 5, 6, 7, 8, 9)
11
Anthony Accioly

Je vais essayer d'expliquer les résultats de toutes les commandes que vous avez essayées.

scala> val l = 1.0 :: 5.5 :: Nil
l: List[Double] = List(1.0, 5.5)

Tout d’abord, List est un alias de type à scala.collection.immutable.List (défini dans Predef.scala).

L'utilisation de l'objet compagnon List est un moyen plus simple d'instancier un List. Ex: List(1.0,5.5)

scala> l
res0: List[Double] = List(1.0, 5.5)

scala> l ::: List(2.2, 3.7)
res1: List[Double] = List(1.0, 5.5, 2.2, 3.7)

::: Renvoie une liste résultant de la concaténation du préfixe de liste donné et de cette liste.

La liste originale n'est pas modifiée

scala> List(l) :+ 2.2
res2: List[Any] = List(List(1.0, 5.5), 2.2)

List(l) est un List[List[Double]] Ce n'est certainement pas ce que vous voulez.

:+ Renvoie une nouvelle liste composée de tous les éléments de cette liste suivis de elem.

Le type est List[Any] Car il s'agit de la superclasse commune entre List[Double] Et Double

scala> l
res3: List[Double] = List(1.0, 5.5)

l n'est pas modifié car aucune méthode sur immutable.List n'a modifié la liste.

8
Yann Moisan

Puisque vous souhaitez ajouter des éléments à une liste existante, vous pouvez utiliser var List [Int], puis continuer à ajouter des éléments à la même liste. Remarque -> Vous devez vous assurer d'insérer un élément dans la liste existante comme suit: -

var l: List [int] = List () // crée une liste vide

l = 3 :: l // ajoute 3 à la tête de la liste

l = 4 :: l // rend int 4 en tête de la liste

// Maintenant, lorsque vous imprimerez l, vous verrez deux éléments dans la liste (4, 3)

1
Aaditya Shukla