Perché utilizzare un iteratore / generatore per implementazioni di valutazione lazy?

3

Questa domanda può essere applicata ad altre lingue, ma riguarda esplicitamente JavaScript.

Ho cercato di scrivere un'implementazione di valutazione pigra per filtrare attraverso una serie di elementi. Il processo di filtro può essere costituito da 2 funzioni, F e G, che controllano un elemento contro una certa logica e restituiscono un booleano che viene utilizzato per determinare se l'elemento apparirà o meno nell'array finale risultante.

Questo è quello che sembrerebbe utilizzare tradizionalmente i metodi incorporati.

const result = elements.filter(F).filter(G);

Questo è il mio primo tentativo di scrivere un metodo di valutazione pigro per gestire lo stesso scenario SENZA restituire array intermittenti e chiamare il metodo intermedio filter :

for (let i = 0; i < elements.length; i++) {
    if (F(elements[i])) {
        if (G(elements[i])) {
            newArray.push(elements[i]);
        }
    }
}

Ora so che il mio codice è strabiliante e sbagliato perché ho guardato altre librerie che usano iteratori e generatori. Perché?

Perché non usare un ciclo for se la collezione è un array? Cosa lo rende più veloce, se lo è?

    
posta MSD 30.09.2016 - 17:35
fonte

1 risposta

1

Si utilizza Lazy Evaluation in modo che il programma non prenda il costo del calcolo, se non è necessario. Il calcolo più veloce possibile è quello che non esegue mai.

Si usa un iteratore / generatore per la valutazione lazy, se l'elemento nel set che si sta dopo dipende dagli elementi precedenti nel set. Questo ti permette di ottenere il prossimo elemento nel set senza ricalcolare tutti gli elementi precedenti.

Ad esempio:

function* fibonacci(){
  var fn1 = 0;
  var fn2 = 1;
  while (true){  
    var current = fn1;
    fn1 = fn2;
    fn2 = current + fn1;
    yield current;
  }
}

var f = fibonacci();
f.next().value;     // 0
f.next().value;     // 1
f.next().value;     // 1
f.next().value;     // 2
f.next().value;     // 3
f.next().value;     // 5
f.next().value;     // 8

Per rispondere alla tua domanda sul perché dovresti scorrere su un array invece di usare un ciclo for, gli iteratori sono componibili dal punto di vista funzionale; i cicli for non lo sono. Iteratori e generatori sono il modo in cui il linguaggio di programmazione passa passando un ciclo for come funzione.

Come esempio di composizione funzionale, è possibile modificare la funzione Fibonacci per accettare una funzione come filtro. Ciò consentirebbe, ad esempio, di specificare che l'iteratore restituisce solo quei numeri nella sequenza che erano pari (divisibile per due).

    
risposta data 30.09.2016 - 18:00
fonte

Leggi altre domande sui tag