0Pricing
Scala for Backend Engineering & Functional Programming · Lezione

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!

  • map trasforma ogni elemento.
  • filter seleziona gli elementi in base a una condizione.
  • reduce combina gli elementi in un unico risultato (richiede una collezione non vuota).
  • fold combina 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

  1. Approfondimento sulle collezioni immutabili
  2. Operazioni funzionali sulle collezioni
  3. Option, Try ed Either per gli errori
← Torna a Scala for Backend Engineering & Functional Programming