문제 상황
다음과 같이 여러 개의 숫자 배열을 값으로 가지는 객체가 있다고 가정해 보겠습니다.
const obj = {
a: [ 15, 23, 36, 49, 104, 211 ],
b: [ 9, 12, 23 ],
c: [ 11, 17, 18, 23, 38 ],
d: [ 13, 21, 23, 27, 40, 85]
};이 객체에 포함된 배열의 개수는 고정되어 있지 않으며, 임의의 개수만큼 존재할 수 있습니다.
우리는 이러한 객체를 인수로 받아, 모든 배열에 공통으로 포함된 요소들만 모은 새로운 배열을 반환하는 자바스크립트 함수를 작성해야 합니다.
따라서 위 객체를 예로 들 때 기대하는 출력 결과는 다음과 같습니다.
const output = [23];
풀이 접근 방식
이 문제는 두 단계로 나누어 해결할 수 있습니다.
1단계: 두 배열의 교집합 구하기
먼저 두 배열을 비교해 공통 요소만 추출하는 헬퍼 함수를 만듭니다. 첫 번째 배열의 각 요소를 순회하면서 includes() 메서드로 해당 요소가 두 번째 배열에 존재하는지 확인하고, 존재한다면 결과 배열에 추가합니다.
2단계: 여러 배열로 확장하기
그다음 객체의 키 목록을 가져온 뒤, 첫 번째 배열을 초기값으로 설정하고 나머지 배열들과 차례대로 교집합을 구해 나갑니다. 중간에 결과가 빈 배열이 되었다면 더 이상 공통 요소가 없다는 의미이므로, 불필요한 연산을 줄이기 위해 즉시 빈 배열을 반환하도록 처리했습니다.
예제 코드
const obj = {
a: [ 15, 23, 36, 49, 104, 211 ],
b: [ 9, 12, 23 ],
c: [ 11, 17, 18, 23, 38 ],
d: [ 13, 21, 23, 27, 40, 85]
};
const commonBetweenTwo = (arr1, arr2) => {
const res = [];
for(let i = 0; i < arr1.length; i++){
if(arr2.includes(arr1[i])){
res.push(arr1[i]);
};
};
return res;
};
const commonBetweenMany = (obj = {}) => {
const keys = Object.keys(obj);
let res = obj[keys[0]];
for(let i = 1; i < keys.length; i++){
res = commonBetweenTwo(res, obj[keys[i]]);
if(!res.length){
return [];
};
};
return res;
};
console.log(commonBetweenMany(obj));위 코드에서 commonBetweenMany() 함수는 객체의 모든 키를 대상으로 반복하므로, 배열이 몇 개 추가되더라도 동일한 로직으로 동작합니다. 또한 중간에 공통 요소가 하나도 남지 않으면 바로 종료하기 때문에 배열의 개수가 많아져도 효율적으로 처리됩니다.
출력 결과
콘솔에 출력되는 결과는 다음과 같습니다.
[23]