saverioriotto.it

Lavorare con Collezioni in Rust: Vettori, Array e Iteratori

Scopri come lavorare con collezioni in Rust: array, slice, vettori, HashMap e BTreeMap. Impara a usare gli iteratori e metodi funzionali come map e filter con esempi pratici.

Lavorare con Collezioni in Rust: Vettori, Array e Iteratori

Rust offre un insieme ricco e versatile di collezioni per gestire e manipolare dati in modo sicuro ed efficiente. In questa lezione, esploreremo le collezioni più comuni, come array, slice, vettori, HashMap e BTreeMap. Inoltre, imparerai a lavorare con gli iteratori e metodi funzionali per elaborare dati in modo dichiarativo.

Array, Slice e Vettori (Vec)

Array

Un array in Rust è una collezione di elementi con dimensione fissa. Ogni elemento deve avere lo stesso tipo.

fn main() {
    let numeri = [1, 2, 3, 4, 5]; // Array di 5 elementi
    println!("Primo elemento: {}", numeri[0]);
    println!("Lunghezza: {}", numeri.len());
}

Gli array sono ideali per dati con dimensioni conosciute a tempo di compilazione.

Slice

Una slice è una vista su una porzione di un array o un vettore. Ti consente di lavorare su una parte dei dati senza copiarli.

fn main() {
    let numeri = [1, 2, 3, 4, 5];
    let slice = &numeri[1..4]; // Slice degli elementi da indice 1 a 3
    println!("{:?}", slice);
}

Vettori (Vec)

I vettori sono una collezione dinamica che può crescere o ridursi a runtime. Sono molto comuni in Rust.

fn main() {
    let mut numeri = vec![1, 2, 3];
    numeri.push(4); // Aggiungi un elemento
    println!("{:?}", numeri);

    numeri.pop(); // Rimuovi l'ultimo elemento
    println!("{:?}", numeri);
}

I vettori offrono metodi utili come push, pop, e len per manipolare i dati.

HashMap e BTreeMap

HashMap

Un HashMap è una collezione chiave-valore non ordinata. È utile per cercare dati in modo rapido.

use std::collections::HashMap;

fn main() {
    let mut studenti = HashMap::new();
    studenti.insert("Alice", 85);
    studenti.insert("Bob", 92);

    if let Some(&punteggio) = studenti.get("Alice") {
        println!("Punteggio di Alice: {}", punteggio);
    }

    for (nome, punteggio) in &studenti {
        println!("{}: {}", nome, punteggio);
    }
}

BTreeMap

Un BTreeMap è simile a HashMap, ma mantiene le chiavi ordinate.

use std::collections::BTreeMap;

fn main() {
    let mut numeri = BTreeMap::new();
    numeri.insert(3, "Tre");
    numeri.insert(1, "Uno");
    numeri.insert(2, "Due");

    for (chiave, valore) in &numeri {
        println!("{}: {}", chiave, valore);
    }
}

Iteratori e Metodi Funzionali

Gli iteratori permettono di scorrere e trasformare i dati in modo dichiarativo. Puoi creare un iteratore da collezioni come vettori, array o slice.

Iterazione con for

fn main() {
    let numeri = vec![1, 2, 3, 4, 5];
    for n in &numeri {
        println!("{}", n);
    }
}

Metodi Funzionali: map e filter

  • map: Trasforma ogni elemento.
  • filter: Seleziona elementi che soddisfano una condizione.
fn main() {
    let numeri = vec![1, 2, 3, 4, 5];

    // Moltiplica ogni elemento per 2
    let doppi = numeri.iter().map(|x| x * 2).collect::>();
    println!("{:?}", doppi);

    // Filtra numeri pari
    let pari = numeri.iter().filter(|&&x| x % 2 == 0).collect::>();
    println!("{:?}", pari);
}

Esercizi Pratici

  1. Elaborare Dati da un Array
    Scrivi una funzione che accetta un array di numeri interi e restituisce un vettore con i numeri moltiplicati per 3.

    Soluzione:

    fn moltiplica(array: &[i32]) -> Vec {
        array.iter().map(|x| x * 3).collect()
    }
    
    fn main() {
        let numeri = [1, 2, 3, 4, 5];
        let risultato = moltiplica(&numeri);
        println!("{:?}", risultato);
    }
  2. Trovare Valori Duplicati
    Scrivi una funzione che trova e restituisce i numeri duplicati in un vettore.

    Soluzione:

    use std::collections::HashSet;
    
    fn trova_duplicati(vettore: &[i32]) -> Vec {
        let mut visti = HashSet::new();
        let mut duplicati = Vec::new();
    
        for &numero in vettore {
            if !visti.insert(numero) {
                duplicati.push(numero);
            }
        }
        duplicati
    }
    
    fn main() {
        let numeri = vec![1, 2, 3, 4, 1, 2, 5];
        let duplicati = trova_duplicati(&numeri);
        println!("Duplicati: {:?}", duplicati);
    }

Conclusione

Le collezioni e gli iteratori in Rust ti forniscono strumenti potenti per gestire e manipolare dati in modo flessibile ed efficiente. Comprendere il funzionamento di array, slice, vettori, HashMap, BTreeMap ti permetterà di scrivere codice più chiaro e conciso. Nel prossimo articolo esploreremo metodi funzionali come Closure, Map e Filter. Prova gli esercizi proposti per consolidare i concetti e padroneggiare l'uso di collezioni e iteratori in Rust! 




Commenti
* Obbligatorio