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 zip
perilaku 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_longest
perilaku Python , menyisipkan di undefined
mana 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 zip
pada string, rentang, objek peta, dll.), Anda bisa menentukan yang berikut:
function iterView(iterable) {
// returns an array equivalent to the iterable
}
Namun jika Anda menulis zip
dengan 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.)