2016年の更新:
以下は、すっきりとしたEcmascript 6バージョンです。
zip= rows=>rows[0].map((_,c)=>rows.map(row=>row[c]))
イラスト相当 Pythonの { zip(*args)
}:
> zip([['row0col0', 'row0col1', 'row0col2'],
['row1col0', 'row1col1', 'row1col2']]);
[["row0col0","row1col0"],
["row0col1","row1col1"],
["row0col2","row1col2"]]
(とFizzyTeaは、次の関数定義は、Pythonのように振る舞うが、免責事項は下記を参照してください...これがそう、それ自身の逆ではありませんでしょうのでES6は、可変長引数の構文を持っていることを指摘zip(zip(x))
しません等しいx
マット・クレイマーが指摘するようにかかわらず、zip(...zip(...x))==x
のような(通常のPython zip(*zip(*x))==x
では))
同等の代替定義。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
(...
現時点では、また将来的には構文にパフォーマンスの問題が発生する可能性があるため、可変引数を使用して2番目の回答を使用する場合は、パフォーマンステストを実行することをお勧めします。)
ここにワンライナーがあります:
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(...)
上記は、配列が同じサイズであることを前提としています。また、引数リストが可変長であるPythonのバージョンとは異なり、リスト引数の単一のリストを渡すことを前提としています。これらすべての「機能」が必要な場合は、以下を参照してください。わずか約2行のコードが追加されます。
以下はzip
、配列のサイズが等しくないエッジケースでのPythonの動作を模倣し、配列の長い部分が存在しないふりをします。
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()
// []
これは、配列が定義されていない場所itertools.zip_longest
に挿入してundefined
、Pythonの動作を模倣します。
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()
// []
これら最後の2つのバージョン(さまざまな別名、複数引数バージョン)を使用する場合、zipは独自の逆ではなくなります。zip(*[...])
Python のイディオムを模倣するにはzip.apply(this, [...])
、zip関数を反転する場合、または同様に可変数のリストを入力として使用する場合に行う必要があります。
補遺:
これを反復可能にするには(たとえば、Pythonではzip
文字列、範囲、マップオブジェクトなどで使用できます)、次のように定義できます。
function iterView(iterable) {
// returns an array equivalent to the iterable
}
ただしzip
、次のように記述すれば、それは不要です。
function zip(arrays) {
return Array.apply(null,Array(arrays[0].length)).map(function(_,i){
return arrays.map(function(array){return array[i]})
});
}
デモ:
> JSON.stringify( zip(['abcde',[1,2,3,4,5]]) )
[["a",1],["b",2],["c",3],["d",4],["e",5]]
(または、range(...)
すでに記述している場合はPythonスタイルの関数を使用できます。最終的には、ECMAScript配列内包表記またはジェネレーターを使用できるようになります。)