38 votes

Quelle est la meilleure façon de créer un tableau à croissance dynamique en Scala ?

Je voulais ajouter des éléments dynamiquement dans un tableau. Mais il semble que les tableaux et les listes Scala ne fournissent aucune méthode pour ajouter des éléments dynamiquement en raison de leur nature immuable.

J'ai donc décidé d'utiliser le type de données List pour exploiter cette possibilité : : pour y parvenir. Mon code ressemble à ceci

var outList = List(Nil)
val strArray = Array("ram","sam","bam")

for (str<-strArray)
     outList = str :: outList

Bien que cela fonctionne d'une certaine manière, le problème est que les nouvelles chaînes sont pré-apposées dans la liste. Mais l'exigence idéale est l'ordre des données. Oui, je sais ce que vous pensez, vous pouvez inverser la liste des résultats finaux pour retrouver l'ordre original. Mais le problème est qu'il s'agit d'un énorme tableau. Et je crois que ce n'est pas une solution, même si elle résout le problème. Je pense qu'il devrait y avoir un moyen simple de résoudre ce problème...

Et la raison pour laquelle j'ai hacké Scala est d'apprendre la manière fonctionnelle de coder. Ayant var (type mutable) et remplir la liste à la volée ne me semble pas être une façon fonctionnelle de résoudre les problèmes.

Comment faire ?

Idéalement, je voudrais obtenir quelque chose comme cela en Scala (en dessous de l'élément C# code)

List<int> ls = new List<int>();    
for (int i = 0; i < 100; i++)
    ls.Add(i);

35voto

Alexey Romanov Points 39124

Mais il semble que Scala Arrays & Lists ne fournisse aucune méthode pour ajouter des éléments dynamiquement en raison de leur nature immuable.

Eh bien, non. Les tableaux Scala sont des tableaux Java, ils sont donc sont mutable :

val arr = Array(1,2)

arr(0) = 3 // arr == Array(3, 2)

Mais tout comme les tableaux Java (et C/C++/C#/etc.), vous ne pouvez pas modifier les tableaux la taille d'un tableau.

Vous avez donc besoin d'une autre collection, qui est soutenue par un tableau, mais qui permet le redimensionnement. Une collection appropriée en Scala est scala.collection.mutable.ArrayBuffer , java.util.ArrayList en Java, etc.

Si vous souhaitez obtenir un List au lieu d'un Array en fin de compte, utiliser scala.collection.mutable.ListBuffer au lieu de cela.

5voto

olle kullberg Points 4916

Si vous souhaitez travailler avec des structures immuables, vous pouvez utiliser la méthode ++ :

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

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

scala> val newList = orgList ++ list2Add
newList: List[Int] = List(1, 2, 3, 4, 5, 6)

Si vous voulez faire plus que simplement ajouter des éléments, vous pouvez utiliser des fonctions d'ordre supérieur :

val newList = orgList ++ list2Add.map(_ * 2)
newList: List[Int] = List(1, 2, 3, 8, 10, 12)

Ou avec une boucle "for" :

val newList = orgList ++ {for(x <- list2Add) yield 2*x}

Vous pouvez également créer une boucle récursive :

def addAll(toList: List[Int], fromList: List[Int]): List[Int] =
  fromList match {
    case x :: tail => addAll(2*x :: toList, tail)
    case Nil => toList
  }

val newList = addAll(orgList, list2Add )

mais dans ce cas, l'ordre des éléments ajoutés sera inversé :

List(12, 10, 8, 1, 2, 3)

Si vous voulez être performant lorsque vous travaillez avec des listes, il est préférable d'inverser le résultat plutôt que d'essayer d'ajouter de nouveaux éléments à la fin. Ajouter des éléments à la fin d'une liste n'est pas bon :-)

4voto

Enrico Susatyo Points 3873

La réponse de retronym a été prise en compte :

Si vous souhaitez toujours utiliser la liste, il existe plusieurs façons d'ajouter un élément à la liste. Ce que vous pouvez faire est (oui, la partie supérieure est toujours fausse) :

scala> var outList : List[String] = Nil
outList: List[String] = List()

scala> val strArray = Array("a","b","c")
strArray: Array[java.lang.String] = Array(a, b, c)

scala> for(s <- strArray)      
     | outList = outList :+ s

scala> outList
res2: List[String] = List(a, b, c)

Notez l'opérateur :+. Si vous préférez ajouter, vous utiliserez s + : outList.

Qui a dit que programmer en Scala n'était pas amusant ? ;)

P.S. La raison pour laquelle vous voudriez les rendre immuables est peut-être la vitesse. Le traitement de données volumineuses sera plus efficace avec des types de données immuables. N'est-ce pas ?

4voto

michael.kebe Points 5723

Si vous voulez utiliser un Buffer mutable, comme l'a mentionné retronym. Cela ressemble à ceci :

scala> var outList = scala.collection.mutable.Buffer[String]()
outList: scala.collection.mutable.Buffer[String] = ArrayBuffer()

scala> for(str<-strArray) outList += str                          

scala> outList
res10: scala.collection.mutable.ListBuffer[String] = ListBuffer(ram, sam, bam)

Quoi qu'il en soit, il est peut-être préférable de faire directement les choses que l'on veut faire avec l'outil strArray . Par exemple

strArray map(_.toUpperCase) foreach(println)

3voto

retronym Points 35066

D'accord, il y a quelques points à éclaircir.

C'est faux, vous créez une liste à un seul élément, contenant une liste vide :

scala> var outList = List(Nil) 
outList: List[object Nil] = List(List())

Nil est la liste vide :

scala> var outList: List[String] = Nil
outList: List[String] = List()

Ou, si vous préférez :

scala> var outList = List[String]() 
outList: List[String] = List()

Sans plus de contexte, il est difficile de savoir ce que vous entendez par "dynamiquement". Il serait préférable d'écrire votre code d'exemple comme suit :

scala> val strArray = Array("ram","sam","bam")
strArray: Array[java.lang.String] = Array(ram, sam, bam)

scala> strArray toList
res0: List[java.lang.String] = List(ram, sam, bam)

Si vous souhaitez une collection mutable capable de croître et de gérer efficacement les opérations de prépension, d'appendice et d'insertion, vous pouvez utiliser scala.mutable.Buffer .

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X