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

JavaScript에서 두 객체의 Union(합집합) 구현하기

JavaScript로 개발하다 보면 서로 형태가 다른 두 객체를 하나의 객체로 병합해야 하는 경우가 종종 있습니다. 이번 글에서는 값의 타입이 서로 다른 두 객체를 합쳐, 각 키의 값들을 하나의 배열로 모으는 Union 함수를 구현하는 방법을 알아보겠습니다.

문제 정의

먼저, 값이 문자열인 첫 번째 객체가 있다고 가정해 보겠습니다.

const obj1 = { name: " ", email: " " };

그리고 두 번째 객체는 동일한 키를 가지고 있지만, 값이 배열 형태입니다.

const obj2 = { name: ['x'], email: ['y']};

목표는 이 두 객체를 하나의 객체로 합치는 것입니다. 각 키(name, email)의 최종 값에는 첫 번째 객체의 값과 두 번째 객체의 값이 모두 포함되어야 합니다. 즉, 원하는 출력 결과는 다음과 같습니다.

const output = { name: [" ", ['x']], email: [" ", ['y']] };

예제 코드

위 문제를 해결하는 코드는 다음과 같습니다.

const obj1 = { name: " ", email: " " };
const obj2 = { name: ['x'], email: ['y']};
const objectUnion = (obj1 = {}, obj2 = {}) => {
    const obj3 = {
        name:[],
        email:[]
    };
    for(let i in obj1) {
        obj3[i].push(obj1[i]);
    }
    for(let i in obj2) {
        obj3[i].push(obj2[i]);
    }
    return obj3;
};
console.log(objectUnion(obj1, obj2));

실행 결과

위 코드를 실행하면 콘솔에 다음과 같은 결과가 출력됩니다.

{ name: [ ' ', [ 'x' ] ], email: [ ' ', [ 'y' ] ] }

코드 동작 원리

함수의 동작 과정을 단계별로 살펴보면 다음과 같습니다.

  • 결과 객체 초기화: obj3를 생성할 때 name과 email 키를 빈 배열([])로 미리 선언합니다. 이 배열들에 두 객체의 값이 차례대로 쌓이게 됩니다.
  • 첫 번째 객체 순회: for...in 루프로 obj1의 모든 키를 순회하며, 각 키의 값을 obj3의 같은 이름을 가진 배열에 push 합니다.
  • 두 번째 객체 순회: 동일한 방식으로 obj2의 값들도 obj3에 추가합니다. 덕분에 문자열 값과 배열 값이 하나의 배열 안에 함께 들어가게 됩니다.
  • 결과 반환: 모든 값이 병합된 obj3를 최종적으로 반환합니다.

참고: 어떤 키든 처리 가능한 범용 버전

위 예제는 name과 email이라는 특정 키에 한정되어 있어, 키가 바뀌면 코드를 수정해야 하는 단점이 있습니다. 객체가 가진 키를 자동으로 인식해 병합하는 좀 더 유연한 함수가 필요하다면 아래처럼 작성할 수 있습니다.

const objectUnionGeneric = (obj1 = {}, obj2 = {}) => {
    const keys = new Set([...Object.keys(obj1), ...Object.keys(obj2)]);
    const result = {};
    for(const key of keys) {
        result[key] = [].concat(obj1[key] ?? [], obj2[key] ?? []);
    }
    return result;
};
console.log(objectUnionGeneric(obj1, obj2));
// { name: [ ' ', [ 'x' ] ], email: [ ' ', [ 'y' ] ] }

이 버전은 Object.keys()와 Set을 활용해 두 객체의 모든 키를 중복 없이 수집하고, concat()으로 값을 하나의 배열로 합칩니다. 또한 널 병합 연산자(??)를 사용해 한쪽 객체에만 존재하는 키도 오류 없이 처리할 수 있습니다. 키의 개수나 이름이 달라져도 코드 수정 없이 그대로 동작하므로, 실무에서 재사용하기에 훨씬 유리합니다.