Computer >> 컴퓨터 >  >> 프로그래밍 >> JavaScript

JavaScript로 두 배열의 모든 조합 만들기 – 카테시안 곱 객체 배열 생성 방법

두 개의 문자열 배열이 있다고 가정해 보겠습니다. 하나는 사용자 이름 목록을 담고 있고, 다른 하나는 각 사용자에게 연결할 데이터(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)해 주기 때문에, 각 사용자별로 생성된 객체 배열들이 자동으로 하나의 배열로 합쳐집니다. 코드가 훨씬 짧고 선언적이어서 가독성 면에서 큰 장점이 있습니다.