Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Renoir offre una moltitudine di operatori per trasformare e manipolare stream di dati. In questa sezione, vedremo come utilizzare gli operatori di base per eseguire trasformazioni sequenziali su uno stream.

Una trasformazione sequenziale è un’operazione che viene applicata a ogni elemento dello stream una volta in sequenza. Questo ci permette di ottenere il massimo livello di parallelismo e di distribuire il carico equamente tra le risorse disponibili.

Map

L’operatore map è usato per applicare una funzione a ogni elemento dello stream. La funzione può essere qualsiasi closure che prende un elemento dello stream come input e ritorna un nuovo elemento.

#![allow(unused)]
fn main() {
// Moltiplica ogni elemento dello stream per 10
let res = s.map(|n| n * 10).collect_vec();
}

L’operatore map, dato che è applicato a ogni elemento indipendentemente, può usare tutto il potere del parallelismo.

RichMap

L’operatore rich_map è simile all’operatore map ma permette di mantenere uno stato tra gli elementi dello stream. La funzione passata all’operatore rich_map può essere stateful e mantenere uno stato per ogni replica.

#![allow(unused)]
fn main() {
// Enumera gli elementi dello stream
let res = s.rich_map({
    let mut id = 0;
    move |x| {
        id += 1;
 (id - 1, x)
 }
}).collect_vec();
}

Nota che lo stato è mantenuto per ogni replica dell’operatore, quindi in questo caso, se manteniamo il parallelismo ci saranno elementi multipli con lo stesso ID (uno per ogni replica).

Filter

L’operatore filter è usato per mantenere solo gli elementi dello stream che soddisfano una certa condizione. La funzione passata all’operatore filter deve ritornare un valore booleano.

#![allow(unused)]
fn main() {
// Mantieni solo gli elementi pari dello stream
let res = s.filter(|&n| n % 2 == 0).collect_vec();
}

L’operatore filter, dato che è applicato a ogni elemento indipendentemente, può usare tutto il potere del parallelismo.

Flatten

L’operatore flatten è usato per appiattire uno stream di collezioni di elementi. Prende uno stream di container e ritorna uno stream con tutti gli elementi contenuti.

#![allow(unused)]
fn main() {
let s = env.stream_iter((vec![
    vec![1, 2, 3],
    vec![],
    vec![4, 5],
].into_iter()));
let res = s.flatten().collect_vec();
env.execute_blocking();

assert_eq!(res.get().unwrap(), vec![1, 2, 3, 4, 5]);
}

Concatenazione di Operatori Sequenziali

Per aiutare l’utente a scrivere codice pulito e leggibile, Renoir offre una serie di concatenazioni degli operatori precedenti in una singola chiamata. Questo permette di scrivere trasformazioni complesse in una singola riga di codice. Da concatenazioni semplici come flat_map dove il risultato di una map viene appiattito, a quelle più complesse come rich_filter_map dove l’utente può eseguire una map e filter stateful in una singola operazione.

Per una lista completa degli operatori vedi la documentazione API.