Equivalente Javascript della funzione zip di Python


5 Answers

Controlla la libreria Underscore .

Underscore offre oltre 100 funzioni che supportano entrambi i tuoi aiutanti funzionali giornalieri preferiti: mappa, filtro, richiama - oltre a chicche più specializzate: binding di funzioni, javascript templating, creazione di indici rapidi, test di uguaglianza profonda e così via.

- Di 'le persone che l'hanno fatto

Recentemente ho iniziato a usarlo appositamente per la funzione zip() e ha lasciato un'ottima impressione. Sto usando jQuery e CoffeeScript, e si adatta perfettamente a loro. Underscore riprende proprio dove lasciano e finora non mi ha deluso. Oh, a proposito, è solo 3kb minified.

Controlla.

Question

Esiste un equivalente javascript della funzione zip di Python? Cioè, dato che due array di uguale lunghezza creano una serie di coppie.

Ad esempio, se ho tre matrici che assomigliano a questo:

var array1 = [1, 2, 3];
var array2 = ['a','b','c'];
var array3 = [4, 5, 6];

L'array di output dovrebbe essere:

var output array:[[1,'a',4], [2,'b',5], [3,'c',6]]



Esempio ES6 moderno con un generatore:

function *zip (...iterables){
    let iterators = iterables.map(i => i[Symbol.iterator]() )
    while (true) {
        let results = iterators.map(iter => iter.next() )
        if (results.some(res => res.done) ) return
        else yield results.map(res => res.value )
    }
}

Innanzitutto, otteniamo un elenco di iterabili come iterators . Questo di solito accade in modo trasparente, ma qui lo facciamo esplicitamente, mentre produciamo passo dopo passo fino a quando uno di essi è esaurito. Controlliamo se uno qualsiasi dei risultati (usando il metodo .some() ) nell'array dato è esaurito, e in caso affermativo, interrompiamo il ciclo while.




Ho fatto una corsa a questo in puro JS chiedendomi come i plug-in pubblicati sopra avessero fatto il lavoro. Ecco il mio risultato. Premetterò questo dicendo che non ho idea di quanto stabile sarà in IE e simili. È solo un rapido mockup.

init();

function init() {
    var one = [0, 1, 2, 3];
    var two = [4, 5, 6, 7];
    var three = [8, 9, 10, 11, 12];
    var four = zip(one, two, one);
    //returns array
    //four = zip(one, two, three);
    //returns false since three.length !== two.length
    console.log(four);
}

function zip() {
    for (var i = 0; i < arguments.length; i++) {
        if (!arguments[i].length || !arguments.toString()) {
            return false;
        }
        if (i >= 1) {
            if (arguments[i].length !== arguments[i - 1].length) {
                return false;
            }
        }
    }
    var zipped = [];
    for (var j = 0; j < arguments[0].length; j++) {
        var toBeZipped = [];
        for (var k = 0; k < arguments.length; k++) {
            toBeZipped.push(arguments[k][j]);
        }
        zipped.push(toBeZipped);
    }
    return zipped;
}

Non è a prova di proiettile, ma è comunque interessante.




Un'altra variazione di Ddi's :

function* iter(it) {
    yield* it;
}

function* zip(...its) {
    its = its.map(iter);
    while (true) {
        let rs = its.map(it => it.next());
        if (rs.some(r => r.done))
            return;
        yield rs.map(r => r.value);
    }
}

for (let r of zip([1,2,3], [4,5,6,7], [8,9,0,11,22]))
    console.log(r.join())

// the only change for "longest" is some -> every

function* zipLongest(...its) {
    its = its.map(iter);
    while (true) {
        let rs = its.map(it => it.next());
        if (rs.every(r => r.done))
            return;
        yield rs.map(r => r.value);
    }
}

for (let r of zipLongest([1,2,3], [4,5,6,7], [8,9,0,11,22]))
    console.log(r.join())

E questo è come scrivere py's classic zip(*[iter(a)]*n) :

triples = [...zip(...Array(3).fill(iter(a)))]



Non integrato in JavaScript stesso. Alcuni dei comuni framework Javascript (come Prototype) forniscono un'implementazione, oppure puoi scrivere i tuoi.




pythonic offre zip lungo alcune altre funzioni simili a Python:

import {zip} from 'pythonic';

const arr1 = ['a', 'b'];
const arr2 = ['c', 'd', 'e'];
for (const [first, second] of zip(arr1, arr2))
    console.log(`first: ${first}, second: ${second}`);
// first: a, second: c
// first: b, second: d



Related