Hiérarchie des collections
En Scala, toutes les collections héritent du trait Iterable. On distingue trois grandes familles : Seq, Set et Map. Chaque famille propose généralement deux versions :
- Immuables :
scala.collection.immutable— toute modification retouren une nouvelle collection. - Mutables :
scala.collection.mutable— la collection est modifiée en place.
Par défaut, Scala privilégie les collections immuables.
Tableaux
Le type Array est un tableau Java : taille fixe, mais cellules modifiables.
Tableau de taille fixe
object DemoTableaux {
def main(args: Array[String]): Unit = {
val scores = new Array[Int](4)
scores(0) = 15
scores(1) = 12
scores(2) = 18
val initiaux = Array(10, 20, 30, 40)
println(scores(0))
for (i <- scores.indices) println(scores(i))
for (valeur <- initiaux) println(valeur)
val it = scores.iterator
while (it.hasNext) println(it.next())
initiaux.foreach(println)
println(initiaux.mkString(" ; "))
}
}
Tableau dynamique
import scala.collection.mutable.ArrayBuffer
object DemoBuffers {
def main(args: Array[String]): Unit = {
val dyn = ArrayBuffer[Int]()
val predef = ArrayBuffer(25, 37, 98)
dyn += 19
77 +=: dyn
dyn.append(36)
dyn.prepend(52, 34)
dyn.insert(2, 32, 59)
dyn.remove(0)
dyn.remove(1, 2)
dyn -= 36
println(dyn)
println(predef)
}
}
Conversions
import scala.collection.mutable.ArrayBuffer
val extensible: ArrayBuffer[Int] = ArrayBuffer(23, 56, 98)
val fige: Array[Int] = extensible.toArray
val deNouveauExtensible = fige.toBuffer
Tableaux multidimensionnels
object DemoMatrices {
def main(args: Array[String]): Unit = {
val grille = Array.ofDim[Int](2, 3)
grille(0)(2) = 9
grille(1)(0) = 7
for (ligne <- grille; cellule <- ligne) println(cellule)
for (i <- grille.indices; j <- grille(i).indices) {
print(grille(i)(j) + "\t")
if (j == grille(i).length - 1) println()
}
grille.foreach(_.foreach(println))
}
}
Listes
List est une séquence immutable par défaut. ListBuffer offre une version mutable.
Liste immutable
object DemoListes {
def main(args: Array[String]): Unit = {
val fruits = "pomme" :: "poire" :: "cerise" :: Nil
val autres = List("kiwi", "mangue")
println(fruits(1))
fruits.foreach(println)
val avecFin = fruits :+ "orange"
val avecDebut = "fraise" +: fruits
val concat = fruits ::: autres
val egalement = fruits ++ autres
println(avecFin)
println(concat)
}
}
Liste mutable
import scala.collection.mutable.ListBuffer
object DemoListBuffers {
def main(args: Array[String]): Unit = {
val lb = ListBuffer[Int]()
val remplie = ListBuffer(12, 53, 75)
lb.append(15, 62)
remplie.prepend(32, 25, 64)
lb.insert(0, 19)
lb += 32 += 21
31 +=: lb
remplie(2) = 80
remplie.update(0, 30)
remplie.remove(2)
remplie -= 25
val fusion = lb ++ remplie
lb ++= remplie
println(fusion)
println(lb)
}
}
Ensembles
Par défaut, Set est immutable, non ordonné et sans doublons.
Set immutable
object DemoSets {
def main(args: Array[String]): Unit = {
val s = Set(13, 23, 53, 12, 13, 23, 78)
println(s)
val s2 = s + 20
val s3 = s ++ Set(19, 13, 67, 99)
val s4 = s - 12
println(s2)
println(s3)
println(s4)
}
}
Set mutable
import scala.collection.mutable.Set
object DemoSetsMutables {
def main(args: Array[String]): Unit = {
val ms = Set(13, 23, 53, 12, 13, 23, 78)
println(ms)
ms += 11
val ajoute = ms.add(20)
println(ajoute)
ms -= 13
val supprime = ms.remove(2)
println(supprime)
ms ++= Set(27, 28, 29)
println(ms)
}
}
Associations clé/valeur
Map stocke des paires. La version immutable est utilisée par défaut.
Map immutable
object DemoMaps {
def main(args: Array[String]): Unit = {
val scores = Map("Alice" -> 12, "Bob" -> 15)
println(scores)
scores.foreach(println)
scores.foreach { case (nom, note) => println(s"$nom => $note") }
for (nom <- scores.keys) {
println(s"$nom : ${scores.getOrElse(nom, 0)}")
}
println(scores.get("Alice"))
println(scores.getOrElse("Bob", 0))
println(scores.getOrElse("Inconnu", -1))
}
}
Map mutable
import scala.collection.mutable.Map
object DemoMapsMutables {
def main(args: Array[String]): Unit = {
val scores = Map("Alice" -> 12, "Bob" -> 15)
scores.put("Carol", 18)
scores += ("Dave" -> 10)
scores -= "Alice"
scores.update("Bob", 16)
val complement = Map("Eve" -> 20, "Bob" -> 17)
scores ++= complement
println(scores)
}
}
Tuples
Un tuple regroupe un nombre fixe de valeurs, éventuellement de types différents. L'arité est limitée à 22.
object DemoTuples {
def main(args: Array[String]): Unit = {
val infos: (String, Int, Char, Boolean) = ("scala", 100, 'a', true)
println(infos)
println(infos._1)
println(infos._2)
println(infos.productElement(2))
for (elem <- infos.productIterator) println(elem)
val imbrique = (12, 0.5, ("a", "b", 7))
println(imbrique._3._2)
}
}
Propriétés et parcours
object DemoOperationsCommunes {
def main(args: Array[String]): Unit = {
val seq = List(1, 3, 5, 7, 2, 89, 100)
val ens = Set(23, 34, 423, 75)
println(seq.length)
println(seq.size)
println(ens.size)
for (e <- seq) print(e + " ")
println()
ens.iterator.foreach(e => print(e + " "))
println()
println(seq.contains(23))
println(seq.mkString(" < "))
}
}
Collections dérivées
object DemoDerivees {
def main(args: Array[String]): Unit = {
val a = List(1, 3, 5, 7, 2, 89, 100)
val b = List(3, 89, 32, 6, 5, 2)
println(a.head)
println(a.tail)
println(a.init)
println(a.last)
println(a.reverse)
println(a.take(3))
println(a.takeRight(3))
println(a.drop(3))
println(a.dropRight(1))
println(a.union(b))
println(a.intersect(b))
println(a.diff(b))
println(a.zip(b))
for (fenetre <- a.sliding(3)) println(fenetre)
for (pas <- a.sliding(3, 2)) println(pas)
}
}
Calculs statistiques élémentaires
object DemoCalculsSimples {
def main(args: Array[String]): Unit = {
val nombres = List(5, 1, 8, 2, -3, 4)
val paires = List(("a", 3), ("b", 5), ("c", 9), ("d", 2), ("e", 6))
println(nombres.sum)
println(nombres.product)
println(nombres.max)
println(nombres.min)
println(paires.maxBy(_._2))
println(paires.minBy(_._2))
println(nombres.sorted)
println(nombres.sorted(Ordering[Int].reverse))
println(paires.sortBy(_._2))
println(paires.sortBy(_._2)(Ordering[Int].reverse))
println(nombres.sortWith(_ < _))
println(nombres.sortWith(_ > _))
}
}
Fonctions d'ordre supérieur
Filter, map, flatMap et groupBy
object DemoFonctionsOrdreSuperieur {
def main(args: Array[String]): Unit = {
val entiers = List(1, 2, 3, 4, 5, 6, 7)
val pairs = entiers.filter(_ % 2 == 0)
val doubles = entiers.map(_ * 2)
val imbrique = List(List(1, 2, 3), List(6, 7), List(4, 5))
val plat = imbrique.flatten
val phrases = List("bonjour le monde", "scala c est top")
val mots = phrases.flatMap(_.split(" "))
val groupes = entiers.groupBy(n => if (n % 2 == 0) "pair" else "impair")
println(pairs)
println(doubles)
println(plat)
println(mots)
println(groupes)
}
}
Réductions et accumulations
object DemoReductions {
def main(args: Array[String]): Unit = {
val valeurs = List(1, 2, 3, 4, 5)
println(valeurs.reduce(_ + _))
println(valeurs.reduceLeft(_ - _))
println(valeurs.reduceRight(_ - _))
println(valeurs.fold(0)(_ + _))
println(valeurs.foldLeft(10)(_ - _))
println(valeurs.foldRight(10)(_ - _))
}
}