Pembaruan 2016:
Ini versi Ecmascript 6 yang lebih keren:
zip= rows=>rows[0].map((_,c)=>rows.map(row=>row[c]))
Ilustrasi equiv. ke Python { zip(*args)}:
> zip([['row0col0', 'row0col1', 'row0col2'],
['row1col0', 'row1col1', 'row1col2']]);
[["row0col0","row1col0"],
["row0col1","row1col1"],
["row0col2","row1col2"]]
(dan FizzyTea menunjukkan bahwa ES6 memiliki sintaks argumen variadik, sehingga definisi fungsi berikut akan bertindak seperti python, tetapi lihat di bawah untuk penafian ... ini tidak akan menjadi kebalikannya sendiri sehingga zip(zip(x))tidak akan sama x; meskipun seperti yang ditunjukkan Matt Kramer zip(...zip(...x))==x(seperti dalam python biasazip(*zip(*x))==x ))
Definisi definisi alternatif. ke Python { zip}:
> zip = (...rows) => [...rows[0]].map((_,c) => rows.map(row => row[c]))
> zip( ['row0col0', 'row0col1', 'row0col2'] ,
['row1col0', 'row1col1', 'row1col2'] );
// note zip(row0,row1), not zip(matrix)
same answer as above
(Harap perhatikan bahwa ...sintaksis mungkin memiliki masalah kinerja saat ini, dan mungkin di masa depan, jadi jika Anda menggunakan jawaban kedua dengan argumen variadik, Anda mungkin ingin mengujinya.)
Inilah oneliner:
function zip(arrays) {
return arrays[0].map(function(_,i){
return arrays.map(function(array){return array[i]})
});
}
// > zip([[1,2],[11,22],[111,222]])
// [[1,11,111],[2,22,222]]]
// If you believe the following is a valid return value:
// > zip([])
// []
// then you can special-case it, or just do
// return arrays.length==0 ? [] : arrays[0].map(...)
Di atas mengasumsikan bahwa array memiliki ukuran yang sama, sebagaimana mestinya. Ini juga mengasumsikan Anda memasukkan dalam daftar argumen daftar, tidak seperti versi Python di mana daftar argumen variadic.Jika Anda ingin semua "fitur" ini, lihat di bawah. Hanya dibutuhkan sekitar 2 baris kode tambahan.
Berikut ini akan meniru zipperilaku Python pada kasus tepi di mana array tidak memiliki ukuran yang sama, diam-diam berpura-pura bahwa bagian array yang lebih lama tidak ada:
function zip() {
var args = [].slice.call(arguments);
var shortest = args.length==0 ? [] : args.reduce(function(a,b){
return a.length<b.length ? a : b
});
return shortest.map(function(_,i){
return args.map(function(array){return array[i]})
});
}
// > zip([1,2],[11,22],[111,222,333])
// [[1,11,111],[2,22,222]]]
// > zip()
// []
Ini akan meniru itertools.zip_longestperilaku Python , menyisipkan di undefinedmana array tidak didefinisikan:
function zip() {
var args = [].slice.call(arguments);
var longest = args.reduce(function(a,b){
return a.length>b.length ? a : b
}, []);
return longest.map(function(_,i){
return args.map(function(array){return array[i]})
});
}
// > zip([1,2],[11,22],[111,222,333])
// [[1,11,111],[2,22,222],[null,null,333]]
// > zip()
// []
Jika Anda menggunakan dua versi terakhir ini (variadic alias. Versi multi-argumen), maka zip tidak lagi kebalikannya sendiri. Untuk meniru zip(*[...])idiom dari Python, Anda harus melakukan zip.apply(this, [...])ketika Anda ingin membalikkan fungsi zip atau jika Anda ingin memiliki jumlah daftar variabel yang sama sebagai input.
tambahan :
Untuk membuat ini menangani semua iterable (misalnya dalam Python Anda dapat menggunakan zippada string, rentang, objek peta, dll.), Anda bisa menentukan yang berikut:
function iterView(iterable) {
// returns an array equivalent to the iterable
}
Namun jika Anda menulis zipdengan cara berikut , itu pun tidak perlu:
function zip(arrays) {
return Array.apply(null,Array(arrays[0].length)).map(function(_,i){
return arrays.map(function(array){return array[i]})
});
}
Demo:
> JSON.stringify( zip(['abcde',[1,2,3,4,5]]) )
[["a",1],["b",2],["c",3],["d",4],["e",5]]
(Atau Anda dapat menggunakan range(...)fungsi gaya-Python jika Anda sudah menulisnya. Akhirnya Anda akan dapat menggunakan ECMAScript array array atau generator.)