파이썬의 zip 함수와 동등한 자바 스크립트가 있습니까? 즉, 길이가 같은 여러 배열이 주어지면 쌍 배열을 만듭니다.
예를 들어, 다음과 같은 3 개의 배열이있는 경우 :
var array1 = [1, 2, 3];
var array2 = ['a','b','c'];
var array3 = [4, 5, 6];
출력 배열은 다음과 같아야합니다.
var output array:[[1,'a',4], [2,'b',5], [3,'c',6]]
답변
2016 년 업데이트 :
snazzier Ecmascript 6 버전은 다음과 같습니다.
zip= rows=>rows[0].map((_,c)=>rows.map(row=>row[c]))
그림 equiv. 에 파이썬 { zip(*args)
} :
> zip([['row0col0', 'row0col1', 'row0col2'],
['row1col0', 'row1col1', 'row1col2']]);
[["row0col0","row1col0"],
["row0col1","row1col1"],
["row0col2","row1col2"]]
(그리고 FizzyTea 다음 함수 정의 파이썬처럼 행동하지만, 고지 아래 참조 …이 때문에 자신의 역 없습니다 있도록 ES6는 가변 인수 구문 지적 zip(zip(x))
것 같지 x
맷 크레이머 지적한대로했지만, zip(...zip(...x))==x
추천 ( 일반 파이썬에서 zip(*zip(*x))==x
))
대체 정의 equiv. 에 파이썬 { 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
(현재 ...
구문에 성능 문제가있을 수 있으며 나중에는 가변적 인수와 함께 두 번째 답변을 사용하는 경우 구문 테스트를 수행 할 수 있습니다.)
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(...)
위의 배열은 배열의 크기가 동일해야한다고 가정합니다. 또한 인수 목록이 가변적 인 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()
// []
이 마지막 두 버전 (다양한 여러 인수 버전)을 사용하는 경우 zip은 더 이상 고유 한 역이 아닙니다. zip(*[...])
파이썬 의 관용구 를 모방하려면 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(...)
이미 파이썬 스타일 함수를 작성했다면 사용할 수 있습니다 . 결국 ECMAScript 배열 이해 또는 생성기를 사용할 수 있습니다.)
답변
Underscore 라이브러리를 확인하십시오 .
Underscore는 맵, 필터링, 호출 등 자주 사용하는 기능 지원 도우미 (함수 바인딩, 자바 스크립트 템플릿, 빠른 인덱스 생성, 심도 평등 테스트 등)를 지원하는 100 가지가 넘는 기능을 제공합니다.
– 만든 사람들에게
나는 최근에 그 zip()
기능을 위해 특별히 그것을 사용하기 시작했고 그것은 큰 첫인상을 남겼습니다. jQuery와 CoffeeScript를 사용하고 있으며 완벽하게 사용됩니다. 밑줄은 그들이 떠난 곳에서 바로 집어 들고 지금까지 나를 실망시키지 않았습니다. 그건 그렇고, 그것은 단지 3kb 축소되었습니다.
확인 해봐:
_.zip(['moe', 'larry', 'curly'], [30, 40, 50], [true, false, false]);
// returns [["moe", 30, true], ["larry", 40, false], ["curly", 50, false]]
답변
ninjagecko의 우수하고 포괄적 인 답변 외에도 두 개의 JS 배열을 “tuple-mimic”로 압축하는 데 필요한 모든 것은 다음과 같습니다.
//Arrays: aIn, aOut
Array.prototype.map.call( aIn, function(e,i){return [e, aOut[i]];})
설명 :
Javascript에는 tuples
유형이 없으므로 언어 스펙에서 튜플, 목록 및 세트에 대한 기능이 우선 순위가 높지 않았습니다.
그렇지 않으면, JS> 1.6의 배열 맵을 통해 유사한 동작에 간단한 방식으로 액세스 할 수 있습니다 . ( map
실제로 많은> JS 1.4 엔진에서 JS 엔진 제조업체가 실제로 구현하지는 않지만).
파이썬의 zip
,, izip
… 와의 주요 차이점 은 함수 인수를 필요로하기 map
때문에의 함수 스타일 에서 나온 것 map
입니다. 또한 Array
-instance 의 기능입니다 . Array.prototype.map
입력에 대한 추가 선언이 문제인 경우 대신 사용할 수 있습니다 .
예:
_tarrin = [0..constructor, function(){}, false, undefined, '', 100, 123.324,
2343243243242343242354365476453654625345345, 'sdf23423dsfsdf',
'sdf2324.234dfs','234,234fsf','100,100','100.100']
_parseInt = function(i){return parseInt(i);}
_tarrout = _tarrin.map(_parseInt)
_tarrin.map(function(e,i,a){return [e, _tarrout[i]]})
결과:
//'('+_tarrin.map(function(e,i,a){return [e, _tarrout[i]]}).join('),\n(')+')'
>>
(function Number() { [native code] },NaN),
(function (){},NaN),
(false,NaN),
(,NaN),
(,NaN),
(100,100),
(123.324,123),
(2.3432432432423434e+42,2),
(sdf23423dsfsdf,NaN),
(sdf2324.234dfs,NaN),
(234,234fsf,234),
(100,100,100),
(100.100,100)
관련 성능 :
map
오버 for
루프 사용 :
참조 : [[1,7], [2,8]에 [1,2] 및 [7,8]을 병합하는 가장 효율적인 방법은 무엇입니까
참고 : 기본 유형과 같은 false
및 undefined
에 노출되지 않도록 따라서 프로토 타입 객체 계층 구조를 posess하지 않는 toString
기능. 따라서 출력에서 빈 것으로 표시됩니다.
마찬가지로 parseInt
두번째 인수까지의 숫자를 변환되는베이스 / 기수 번호가 있으며,이 때문에 map
인수 함수의 두번째 인수 인덱스를 통과 래퍼 함수가 사용된다.
답변
발전기가있는 최신 ES6 예 :
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 )
}
}
먼저, 우리는 iterables리스트를 얻는다 iterators
. 이것은 일반적으로 투명하게 발생하지만 여기서는 하나가 소진 될 때까지 단계별로 산출하므로 명시 적으로 수행합니다. .some()
주어진 배열에서 (메소드를 사용하여 ) 결과 가 소진되었는지 확인하고, 그렇다면 루프를 중단합니다.
답변
함께 다른 파이썬과 같은 기능 pythonic
제공하는 zip
평가 게으른 반환의 추가 혜택과 기능, Iterator
그것의 동작에 유사한, 파이썬의 대응 :
import {zip, zipLongest} 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
for (const [first, second] of zipLongest(arr1, arr2))
console.log(`first: ${first}, second: ${second}`);
// first: a, second: c
// first: b, second: d
// first: undefined, second: e
// unzip
const [arrayFirst, arraySecond] = [...zip(...zip(arr1, arr2))];
공개 저는 Pythonic의 저자이자 관리자입니다
답변
파이썬에는 zip과 itertools.zip_longest의 두 가지 기능이 있습니다. JS / ES6에서의 구현은 다음과 같습니다 :
JS / ES6에서 Python의 zip 구현
const zip = (...arrays) => {
const length = Math.min(...arrays.map(arr => arr.length));
return Array.from({ length }, (value, index) => arrays.map((array => array[index])));
};
결과 :
console.log(zip(
[1, 2, 3, 'a'],
[667, false, -378, '337'],
[111],
[11, 221]
));
[[1, 667, 111, 11]]
console.log(zip(
[1, 2, 3, 'a'],
[667, false, -378, '337'],
[111, 212, 323, 433, '1111']
));
[[1, 667, 111], [2, false, 212], [3, -378, 323], [ ‘a’, ‘337’, 433]]
console.log(zip(
[1, 2, 3, 'a'],
[667, false, -378, '337'],
[111],
[]
));
[]
JS / ES6에서 Python의 zip_longest 구현
( https://docs.python.org/3.5/library/itertools.html?highlight=zip_longest#itertools.zip_longest )
const zipLongest = (placeholder = undefined, ...arrays) => {
const length = Math.max(...arrays.map(arr => arr.length));
return Array.from(
{ length }, (value, index) => arrays.map(
array => array.length - 1 >= index ? array[index] : placeholder
)
);
};
결과 :
console.log(zipLongest(
undefined,
[1, 2, 3, 'a'],
[667, false, -378, '337'],
[111],
[]
));
[[1, 667, 111, undefined], [2, false, undefined, undefined],
[3, -378, undefined, undefined], [ ‘a’, ‘337’, undefined, undefined]]
console.log(zipLongest(
null,
[1, 2, 3, 'a'],
[667, false, -378, '337'],
[111],
[]
));
[[1, 667, 111, null], [2, false, null, null], [3, -378, null, null], [ ‘a’, ‘337’, null, null]]
console.log(zipLongest(
'Is None',
[1, 2, 3, 'a'],
[667, false, -378, '337'],
[111],
[]
));
[[1, 667, 111, ‘Is None’], [2, false, ‘Is None’, ‘Is None’],
[3, -378, ‘Is None’, ‘Is None’], [ ‘a ‘,’337 ‘,’없음 ‘,’없음 ‘]]
답변
ES6를 사용하여 유틸리티 기능을 만들 수 있습니다.
const zip = (arr, ...arrs) => {
return arr.map((val, i) => arrs.reduce((a, arr) => [...a, arr[i]], [val]));
}
// example
const array1 = [1, 2, 3];
const array2 = ['a','b','c'];
const array3 = [4, 5, 6];
console.log(zip(array1, array2)); // [[1, 'a'], [2, 'b'], [3, 'c']]
console.log(zip(array1, array2, array3)); // [[1, 'a', 4], [2, 'b', 5], [3, 'c', 6]]
그러나, 위의 솔루션에서 첫 번째 배열의 길이는 출력 배열의 길이를 정의합니다.
여기에 더 많은 제어권이있는 솔루션이 있습니다. 조금 복잡하지만 그만한 가치가 있습니다.
function _zip(func, args) {
const iterators = args.map(arr => arr[Symbol.iterator]());
let iterateInstances = iterators.map((i) => i.next());
ret = []
while(iterateInstances[func](it => !it.done)) {
ret.push(iterateInstances.map(it => it.value));
iterateInstances = iterators.map((i) => i.next());
}
return ret;
}
const array1 = [1, 2, 3];
const array2 = ['a','b','c'];
const array3 = [4, 5, 6];
const zipShort = (...args) => _zip('every', args);
const zipLong = (...args) => _zip('some', args);
console.log(zipShort(array1, array2, array3)) // [[1, 'a', 4], [2, 'b', 5], [3, 'c', 6]]
console.log(zipLong([1,2,3], [4,5,6, 7]))
// [
// [ 1, 4 ],
// [ 2, 5 ],
// [ 3, 6 ],
// [ undefined, 7 ]]