실무에서는 서로 다른 구조의 두 배열을 하나의 기준 값으로 연결해야 하는 경우가 자주 발생합니다. 이번 글에서는 공통 속성값(POSITION)을 기준으로 한 배열의 데이터를 다른 배열에 병합하는 방법을 알아보겠습니다.
문제 상황
다음과 같이 두 개의 배열이 있다고 가정해 보겠습니다.
let arr1 = [
{ "LEVEL": 4, "POSITION": "RGM" },
{ "LEVEL": 5, "POSITION": "GM" },
{ "LEVEL": 5, "POSITION": "GMH" }
]
let arr2 = [
{ "EMAIL": "test1@stc.com", "POSITION": "GM" },
{ "EMAIL": "test2@stc.com", "POSITION": "GMH" },
{ "EMAIL": "test3@stc.com", "POSITION": "RGM" },
{ "EMAIL": "test3@CSR.COM.AU", "POSITION": "GM" }
]여기서 우리가 해야 할 작업은 arr2의 각 객체에 LEVEL 속성을 추가하는 것입니다. 이때 LEVEL 값은 arr1 중에서 POSITION 속성값이 일치하는 객체에서 가져와야 합니다.
해결 방법
arr2를 순회하면서 각 요소의 POSITION 값과 일치하는 항목을 arr1에서 찾은 뒤, 해당 객체의 LEVEL 값을 복사하면 됩니다. 코드로 살펴보겠습니다.
예제 코드
let arr1 = [
{ "LEVEL": 4, "POSITION": "RGM" },
{ "LEVEL": 5, "POSITION": "GM" },
{ "LEVEL": 5, "POSITION": "GMH" }
]
let arr2 = [
{ "EMAIL": "test1@stc.com", "POSITION": "GM" },
{ "EMAIL": "test2@stc.com", "POSITION": "GMH" },
{ "EMAIL": "test3@stc.com", "POSITION": "RGM" },
{ "EMAIL": "test3@CSR.COM.AU", "POSITION": "GM" }
]
const formatArray = (first, second) => {
second.forEach((el, index) => {
const ind = first.findIndex(item => item["POSITION"] === el["POSITION"]);
if (ind !== -1) {
second[index]["LEVEL"] = first[ind]["LEVEL"];
}
});
};
formatArray(arr1, arr2);
console.log(arr2);코드 설명
- forEach(): arr2의 모든 요소를 하나씩 순회합니다.
- findIndex(): arr1에서 현재 요소(el)의 POSITION 값과 동일한 객체의 인덱스를 찾습니다. 일치하는 항목이 없으면 -1을 반환합니다.
- 조건문(if): findIndex의 결과가 -1이 아닌 경우, 즉 일치하는 항목이 존재할 때만 arr2의 해당 객체에 LEVEL 속성을 추가합니다.
실행 결과
콘솔에 출력되는 결과는 다음과 같습니다.
[
{ EMAIL: 'test1@stc.com', POSITION: 'GM', LEVEL: 5 },
{ EMAIL: 'test2@stc.com', POSITION: 'GMH', LEVEL: 5 },
{ EMAIL: 'test3@stc.com', POSITION: 'RGM', LEVEL: 4 },
{ EMAIL: 'test3@CSR.COM.AU', POSITION: 'GM', LEVEL: 5 }
]결과를 보면 arr2의 모든 객체가 POSITION 값을 기준으로 arr1에서 올바른 LEVEL 값을 성공적으로 가져온 것을 확인할 수 있습니다.
참고: 성능 개선 팁
위 방식은 직관적이지만, 배열의 크기가 커지면 O(n×m)의 시간 복잡도로 인해 성능이 저하될 수 있습니다. 데이터 양이 많다면 arr1을 Map 객체로 변환하여 조회 시간을 O(1)로 줄이는 방법을 고려해 보세요.
const levelMap = new Map(arr1.map(item => [item.POSITION, item.LEVEL]));
arr2.forEach(el => {
if (levelMap.has(el.POSITION)) {
el.LEVEL = levelMap.get(el.POSITION);
}
});이처럼 JavaScript의 배열 메서드를 활용하면 공통 키를 기준으로 여러 배열의 데이터를 손쉽게 검색하고 병합할 수 있습니다.