2016 güncellemesi:
İşte daha güzel bir Ecmascript 6 sürümü:
zip= rows=>rows[0].map((_,c)=>rows.map(row=>row[c]))
Çizim eşdeğeri. için Python { zip(*args)
}:
> zip([['row0col0', 'row0col1', 'row0col2'],
['row1col0', 'row1col1', 'row1col2']]);
[["row0col0","row1col0"],
["row0col1","row1col1"],
["row0col2","row1col2"]]
(ve FizzyTea, ES6'nın varyasyon argümanı sözdizimine sahip olduğuna dikkat çekiyor, bu nedenle aşağıdaki işlev tanımı python gibi davranacak, ancak sorumluluk reddi için aşağıya bakın ... bu kendi tersi olmayacak, bu yüzden zip(zip(x))
eşit olmayacak x
; Matt Kramer'ın işaret ettiği zip(...zip(...x))==x
gibi (gibi normal python içinde zip(*zip(*x))==x
))
Alternatif tanım eşdeğeri. için 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
( ...
Sözdiziminin şu anda ve muhtemelen gelecekte performans sorunları olabileceğini unutmayın , bu nedenle ikinci yanıtı değişken değişkenli argümanlarla kullanırsanız, bunu mükemmel bir şekilde test etmek isteyebilirsiniz.)
İşte bir 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(...)
Yukarıdaki, dizilerin olması gerektiği gibi eşit büyüklükte olduğunu varsayar. Ayrıca, Python'un argüman listesinin varyasyonlu versiyonundan farklı olarak tek bir liste argümanı listesine geçtiğinizi varsayar.Bu "özelliklerin" tümünü istiyorsanız , aşağıya bakın. Fazladan 2 satır daha kod gerektirir.
Aşağıdakiler zip
, dizilerin eşit büyüklükte olmadığı, dizilerin daha uzun bölümlerinin mevcut olmadığını sessizce iddia eden uç durumlarda Python'un davranışını taklit edecektir :
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()
// []
Bu, dizilerin tanımlanmadığı yerlere itertools.zip_longest
ekleyerek Python'un davranışını taklit eder undefined
:
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()
// []
Bu son iki sürümü (variadic aka. Çoklu bağımsız değişken sürümleri) kullanıyorsanız, zip artık kendi tersi değildir. zip(*[...])
Python'dan deyimi taklit zip.apply(this, [...])
etmek için zip işlevini ters çevirmek istediğinizde veya giriş olarak değişken sayıda listeye sahip olmak istediğinizde yapmanız gerekir.
ek :
Bu tanıtıcıyı yinelenebilir yapmak için (örneğin, Python'da zip
dizelerde, aralıklarda, harita nesnelerinde vb. Kullanabilirsiniz ) aşağıdakileri tanımlayabilirsiniz:
function iterView(iterable) {
// returns an array equivalent to the iterable
}
Ancak zip
aşağıdaki şekilde yazarsanız , bu bile gerekli olmayacaktır:
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]]
(Ya da range(...)
zaten bir tane yazdıysanız Python tarzı bir işlev kullanabilirsiniz . Sonunda ECMAScript dizi anlayışlarını veya oluşturucularını kullanabilirsiniz.)