Operazioni funzionali sulle collezioni
Padroneggi le operazioni funzionali più comuni, come map, filter, fold e reduce, per trasformare i dati.
Operazioni funzionali sulle collezioni è una lezione Scala for Backend Engineering & Functional Programming gratuita su CoddyKit. Questa è la lezione 2 di 3. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento Scala for Backend Engineering & Functional Programming, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso Scala for Backend Engineering & Functional Programming include 3 lezioni in totale.
Operazioni funzionali: perché usarle?
Le operazioni funzionali sulle collezioni consentono di trasformare e combinare i dati senza modificare la collezione originale. Questo approccio favorisce l'immutabilità e rende il codice più facile da leggere e testare.
Esamineremo operazioni fondamentali come map, filter, reduce e fold.
Trasformare con `map`
L'operazione map applica una funzione a ogni elemento di una collezione e restituisce una nuova collezione contenente i risultati trasformati. La collezione originale rimane invariata.
Provi a eseguire questo esempio:
object Main {
def main(args: Array[String]): Unit = {
val numbers = List(1, 2, 3, 4)
val doubled = numbers.map(n => n * 2)
println(s"Original: $numbers")
println(s"Doubled: $doubled")
}
}`map` con tipi diversi
map è molto flessibile! È possibile trasformare gli elementi in un tipo completamente diverso. In questo caso, convertiamo i numeri in stringhe oppure calcoliamo la lunghezza delle stringhe.
Noti che il risultato è una List[Int], anche se l'input era una List[String].
object Main {
def main(args: Array[String]): Unit = {
val names = List("Alice", "Bob", "Charlie")
val lengths = names.map(name => name.length)
println(s"Names: $names")
println(s"Lengths: $lengths")
}
}Selezionare con `filter`
L'operazione filter crea una nuova collezione contenente solo gli elementi che soddisfano una determinata condizione (una funzione predicato). In questo modo, gli elementi indesiderati vengono esclusi.
Troviamo i numeri pari:
object Main {
def main(args: Array[String]): Unit = {
val numbers = List(1, 2, 3, 4, 5, 6)
val evens = numbers.filter(n => n % 2 == 0)
println(s"Original: $numbers")
println(s"Evens: $evens")
}
}Altri esempi di `filter`
È possibile usare qualsiasi espressione booleana come condizione del filtro. Filtriamo un elenco di parole per mantenere solo quelle con più di 4 caratteri.
object Main {
def main(args: Array[String]): Unit = {
val words = List("apple", "cat", "banana", "dog", "elephant")
val longWords = words.filter(w => w.length > 4)
println(s"Words: $words")
println(s"Long words: $longWords")
}
}Combinare con `reduce`
L'operazione reduce combina tutti gli elementi di una collezione in un unico risultato. Riceve un'operazione binaria (una funzione che accetta due argomenti e ne restituisce uno) e la applica in modo cumulativo.
In questo caso, sommiamo tutti gli elementi:
object Main {
def main(args: Array[String]): Unit = {
val numbers = List(1, 2, 3, 4)
val sum = numbers.reduce((a, b) => a + b)
println(s"Numbers: $numbers")
println(s"Sum: $sum")
}
}`reduce` per prodotto e massimo
reduce può eseguire diverse aggregazioni. È possibile calcolare il prodotto dei numeri o trovare il valore massimo.
Nota: reduce genera un errore se la collezione è vuota.
object Main {
def main(args: Array[String]): Unit = {
val numbers = List(1, 5, 2, 8)
val product = numbers.reduce((a, b) => a * b)
val maxNum = numbers.reduce((a, b) => if (a > b) a else b)
println(s"Numbers: $numbers")
println(s"Product: $product")
println(s"Max: $maxNum")
}
}`fold`: la potenza del valore iniziale
fold è simile a reduce, ma presenta una differenza importante: riceve un valore iniziale (chiamato anche "accumulatore"). Questo lo rende sicuro per le collezioni vuote e consente di ottenere risultati di tipi diversi.
Sommiamo i numeri partendo da 10:
object Main {
def main(args: Array[String]): Unit = {
val numbers = List(1, 2, 3)
// foldLeft(initialValue)(operation)
val sumWithInitial = numbers.foldLeft(10)((acc, n) => acc + n)
println(s"Numbers: $numbers")
println(s"Sum (starting from 10): $sumWithInitial")
}
}Direzione: `foldLeft` e `foldRight`
Scala offre foldLeft e foldRight. Si differenziano per l'ordine in cui elaborano gli elementi e per il modo in cui viene passato l'accumulatore.
foldLeft(initial)(op): elabora da sinistra a destra.foldRight(initial)(op): elabora da destra a sinistra.
Per operazioni come la concatenazione di stringhe, la direzione è importante!
object Main {
def main(args: Array[String]): Unit = {
val chars = List('a', 'b', 'c')
val leftFold = chars.foldLeft("")((acc, c) => acc + c)
val rightFold = chars.foldRight("")((c, acc) => acc + c)
println(s"Chars: $chars")
println(s"foldLeft: $leftFold") // Output: abc
println(s"foldRight: $rightFold") // Output: abc (due to string append order)
// Example where order matters: (acc, char) => char + acc
val rightFoldReversed = chars.foldRight("")((c, acc) => c + acc)
println(s"foldRight (char + acc): $rightFoldReversed") // Output: abc
// A common example where order matters is for operations like subtraction or division, but string concatenation also shows it.
}
}Verifica delle operazioni funzionali
Consideri il seguente frammento di codice Scala:
val data = List(10, 20, 30, 40)
val result1 = data.map(x => x / 10)
val result2 = data.filter(x => x > 25)
val result3 = data.reduce((a, b) => a + b)
Quali delle seguenti affermazioni sui risultati sono VERE?
Riepilogo: la potenza delle operazioni funzionali
Ha acquisito le principali operazioni funzionali!
maptrasforma ogni elemento.filterseleziona gli elementi in base a una condizione.reducecombina gli elementi in un unico risultato (richiede una collezione non vuota).foldcombina gli elementi usando un valore iniziale (è sicuro per le collezioni vuote).
Queste operazioni sono fondamentali per scrivere codice Scala conciso, immutabile e potente. Ora esamineremo una gestione robusta degli errori usando Option, Try ed Either.
Domande Frequenti
La lezione «Operazioni funzionali sulle collezioni» è gratuita?
Sì — il testo completo di «Operazioni funzionali sulle collezioni» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso Scala for Backend Engineering & Functional Programming, passa a CoddyKit PRO. Il corso Scala for Backend Engineering & Functional Programming include 3 lezioni in totale.
Cosa imparerò in «Operazioni funzionali sulle collezioni»?
Padroneggi le operazioni funzionali più comuni, come map, filter, fold e reduce, per trasformare i dati. Eserciti Scala for Backend Engineering & Functional Programming con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.
Ho bisogno di esperienza per iniziare Scala for Backend Engineering & Functional Programming?
Non è richiesta alcuna esperienza precedente. Scala for Backend Engineering & Functional Programming su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 2 di 3.
Quanto tempo richiede la lezione «Operazioni funzionali sulle collezioni»?
La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.
Posso scrivere ed eseguire codice in questa lezione Scala for Backend Engineering & Functional Programming?
Sì. Ogni lezione Scala for Backend Engineering & Functional Programming include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.
Tutte le lezioni di questo corso
- Approfondimento sulle collezioni immutabili
- Operazioni funzionali sulle collezioni
- Option, Try ed Either per gli errori