개요
이번 글에서는 임의의 개수만큼 배열을 인수로 받아, 모든 배열에 공통으로 존재하는 요소만 모아 새로운 배열로 반환하는 JavaScript 함수를 작성해 보겠습니다. 공통 요소가 하나도 없는 경우에는 빈 배열([])을 반환하도록 처리합니다.
예제 데이터
설명을 위해 다음과 같은 세 개의 배열이 있다고 가정해 보겠습니다.
const arr1 = [2, 6, 7, 1, 7, 8, 4, 3]; const arr2 = [5, 7, 2, 2, 1, 3]; const arr3 = [1, 56, 345, 6, 54, 2, 68, 85, 3];
구현 코드
두 배열의 교집합을 구하는 함수와, 이를 여러 배열에 반복적으로 적용하는 함수로 나누어 구현할 수 있습니다.
const arr1 = [2, 6, 7, 1, 7, 8, 4, 3];
const arr2 = [5, 7, 2, 2, 1, 3];
const arr3 = [1, 56, 345, 6, 54, 2, 68, 85, 3];
// 두 배열의 교집합을 구하는 함수
const intersection = (arr1, arr2) => {
const res = [];
for(let i = 0; i < arr1.length; i++){
// 두 번째 배열에 없는 요소는 건너뜀
if(!arr2.includes(arr1[i])){
continue;
};
res.push(arr1[i]);
};
return res;
};
// 여러 개의 배열에 교집합을 순차적으로 적용하는 함수
const intersectMany = (...arrs) => {
let res = arrs[0].slice(); // 첫 번째 배열을 복사하여 시작
for(let i = 1; i < arrs.length; i++){
res = intersection(res, arrs[i]);
};
return res;
};
console.log(intersectMany(arr1, arr2, arr3));
실행 결과
위 코드를 실행하면 콘솔에 다음과 같이 출력됩니다.
[2, 1, 3]
동작 원리
intersection 함수는 첫 번째 배열의 각 요소를 순회하면서, 해당 요소가 두 번째 배열에도 존재하는지 Array.prototype.includes() 메서드로 확인합니다. 존재하는 경우에만 결과 배열에 추가하기 때문에, 최종적으로 반환되는 배열에는 양쪽 배열 모두에 들어 있는 값만 남게 됩니다.
intersectMany 함수는 첫 번째 배열을 복사한 뒤, 나머지 배열들을 차례대로 앞서 만든 intersection 함수에 전달하여 교집합을 점진적으로 좁혀 갑니다. 이 덕분에 배열이 세 개든 열 개든 관계없이 유연하게 확장할 수 있습니다.
세 배열의 공통 요소는 2, 1, 3뿐이므로 최종 결과는 [2, 1, 3]입니다. 만약 어느 배열에도 공통되는 값이 없다면 빈 배열이 반환됩니다.