파이썬에는 여러 개의 반복 가능한(iterable) 객체를 인덱스별로 묶어주는 zip() 함수가 내장되어 있습니다. 이번 글에서는 이와 동일한 기능을 수행하는 JavaScript 함수를 직접 작성해 보겠습니다.
즉, 길이가 같은 여러 개의 배열이 주어졌을 때, 같은 인덱스에 있는 요소들을 하나의 배열로 묶어 새로운 배열을 반환하는 것이 목표입니다.
예를 들어 다음과 같은 세 개의 배열이 있다고 가정해 보겠습니다.
const array1 = [1, 2, 3]; const array2 = ['a','b','c']; const array3 = [4, 5, 6];
이때 원하는 출력 결과는 다음과 같습니다.
const output = [[1,'a',4], [2,'b',5], [3,'c',6]]
zip() 함수 구현하기
이 기능은 reduce(), map(), 또는 단순한 중첩 for 루프 등 다양한 방식으로 구현할 수 있습니다. 여기서는 가독성이 좋은 중첩 forEach() 루프를 활용해 구현해 보겠습니다.
예제 코드
const array1 = [1, 2, 3];
const array2 = ['a','b','c'];
const array3 = [4, 5, 6];
const zip = (...arr) => {
const zipped = [];
arr.forEach((element, ind) => {
element.forEach((el, index) => {
if(!zipped[index]){
zipped[index] = [];
};
if(!zipped[index][ind]){
zipped[index][ind] = [];
}
zipped[index][ind] = el || '';
})
});
return zipped;
};
console.log(zip(array1, array2, array3));동작 원리
이 코드의 핵심 로직은 다음과 같습니다.
첫째, 나머지 매개변수(...arr)를 사용해 전달된 모든 배열을 하나의 배열로 받습니다. 둘째, 바깥쪽 forEach는 각 입력 배열을 순회하고, 안쪽 forEach는 해당 배열의 요소를 순회합니다. 셋째, 아직 존재하지 않는 인덱스 위치에는 빈 배열을 초기화한 뒤, 현재 요소를 알맞은 자리에 배치합니다. 이 과정을 통해 각 인덱스별로 요소들이 자연스럽게 그룹화됩니다.
실행 결과
콘솔에 출력되는 결과는 다음과 같습니다.
[ [ 1, 'a', 4 ], [ 2, 'b', 5 ], [ 3, 'c', 6 ] ]
결과를 보면 첫 번째 배열의 각 요소가 두 번째, 세 번째 배열의 같은 인덱스 요소들과 함께 묶인 것을 확인할 수 있습니다. 이는 파이썬의 zip(array1, array2, array3) 호출 결과와 정확히 동일합니다.
마무리
이처럼 JavaScript에서도 파이썬의 zip 함수와 같은 기능을 몇 줄의 코드로 손쉽게 구현할 수 있습니다. 실무에서는 여러 데이터 소스를 병렬로 처리하거나, 키-값 쌍을 만들 때 유용하게 활용할 수 있으니 상황에 맞게 응용해 보시기 바랍니다.