두 개의 문자열 배열이 있다고 가정해 보겠습니다. 하나는 사용자 이름 목록을 담고 있고, 다른 하나는 각 사용자에게 연결할 데이터(SOP) 목록을 담고 있습니다.
const users = ['Rahul', 'Dinesh', 'Rohit']; const data = ["SOP1", "SOP2", "SOP3", "SOP4"];
여기서 작성해야 할 것은 이런 두 개의 배열을 인자로 받아 새로운 객체 배열을 반환하는 JavaScript 함수입니다.
반환되는 배열에는 users 배열과 data 배열 사이의 모든 가능한 조합마다 하나씩 객체가 포함되어야 합니다. 수학적으로 말하면 두 배열의 카테시안 곱(Cartesian Product)을 구하는 것과 같습니다.
따라서 위 배열을 입력했을 때 기대하는 출력 결과는 다음과 같습니다.
const output = [
{ User: 'Rahul', SOP: 'SOP1' },
{ User: 'Rahul', SOP: 'SOP2' },
{ User: 'Rahul', SOP: 'SOP3' },
{ User: 'Rahul', SOP: 'SOP4' },
{ User: 'Dinesh', SOP: 'SOP1' },
{ User: 'Dinesh', SOP: 'SOP2' },
{ User: 'Dinesh', SOP: 'SOP3' },
{ User: 'Dinesh', SOP: 'SOP4' },
{ User: 'Rohit', SOP: 'SOP1' },
{ User: 'Rohit', SOP: 'SOP2' },
{ User: 'Rohit', SOP: 'SOP3' },
{ User: 'Rohit', SOP: 'SOP4' }
];구현 예제
가장 직관적인 방법은 forEach를 중첩해서 사용하는 것입니다. 바깥쪽 반복문으로 사용자를, 안쪽 반복문으로 데이터를 순회하면서 각 조합을 객체로 만들어 결과 배열에 추가합니다.
const users = ['Rahul', 'Dinesh', 'Rohit'];
const data = ["SOP1", "SOP2", "SOP3", "SOP4"];
const multiplyUserData = (users = [], data = []) => {
const res = [];
users.forEach(user => {
data.forEach(el => {
res.push({
'user': user,
'sop': el
});
});
});
return res;
};
console.log(multiplyUserData(users, data));출력 결과
위 코드를 실행하면 콘솔에 다음과 같이 출력됩니다.
[
{ user: 'Rahul', sop: 'SOP1' },
{ user: 'Rahul', sop: 'SOP2' },
{ user: 'Rahul', sop: 'SOP3' },
{ user: 'Rahul', sop: 'SOP4' },
{ user: 'Dinesh', sop: 'SOP1' },
{ user: 'Dinesh', sop: 'SOP2' },
{ user: 'Dinesh', sop: 'SOP3' },
{ user: 'Dinesh', sop: 'SOP4' },
{ user: 'Rohit', sop: 'SOP1' },
{ user: 'Rohit', sop: 'SOP2' },
{ user: 'Rohit', sop: 'SOP3' },
{ user: 'Rohit', sop: 'SOP4' }
]코드 동작 원리
- 바깥쪽 forEach: users 배열의 각 사용자('Rahul', 'Dinesh', 'Rohit')를 하나씩 순회합니다.
- 안쪽 forEach: 현재 사용자에 대해 data 배열의 모든 값('SOP1'~'SOP4')을 순회합니다.
- 객체 생성 및 push: 매 조합마다
{ user, sop }형태의 객체를 만들어 결과 배열 res에 추가합니다. - 시간 복잡도: users의 길이를 n, data의 길이를 m이라 하면 총 n × m개의 객체가 생성되므로 시간 복잡도는 O(n × m)입니다.
flatMap을 활용한 더 간결한 방법
ES2019에서 도입된 flatMap()을 사용하면 중첩 반복문 없이 한 줄로 같은 결과를 얻을 수 있습니다.
const multiplyUserData = (users = [], data = []) =>
users.flatMap(user => data.map(sop => ({ user, sop })));
console.log(multiplyUserData(users, data));flatMap은 map의 결과를 한 단계 평탄화(flatten)해 주기 때문에, 각 사용자별로 생성된 객체 배열들이 자동으로 하나의 배열로 합쳐집니다. 코드가 훨씬 짧고 선언적이어서 가독성 면에서 큰 장점이 있습니다.