문제 상황
다음과 같이 여러 개의 객체를 담고 있는 배열이 있다고 가정해 보겠습니다.
const arr = [
{
"Country": "BR",
"New Lv1-Lv2": "#N/A"
},
{
"Country": "BR",
"New Lv1-Lv2": "#N/A"
},
{
"Country": "",
"New Lv1-Lv2": "test"
}
];우리가 작성해야 할 JavaScript 함수는 이러한 객체 배열을 입력으로 받아서 다음 두 가지 작업을 수행해야 합니다.
첫째, 중복된 객체를 제거한 새로운 배열을 생성하여 반환해야 합니다. 여기서 '중복'이란 Country 속성의 값이 동일한 객체를 의미합니다.
둘째, 각 객체에 count 속성을 추가해야 하며, 이 값은 해당 객체가 원본 배열에 몇 번 등장했는지를 나타냅니다.
해결 방법
이 문제는 객체를 키-값 형태의 임시 저장소(맵)로 활용하면 효율적으로 해결할 수 있습니다. 배열을 순회하면서 각 객체의 고유 키를 만들고, 처음 등장한 객체는 저장소에 추가한 뒤 등장할 때마다 카운트를 증가시키는 방식입니다.
예제 코드
const arr = [
{
"Country": "BR",
"New Lv1-Lv2": "#N/A"
},
{
"Country": "BR",
"New Lv1-Lv2": "#N/A"
},
{
"Country": "",
"New Lv1-Lv2": "test"
}
];
const convert = (arr) => {
const res = {};
arr.forEach((obj) => {
// Country와 New Lv1-Lv2 값을 조합해 고유 키 생성
const key = `${obj.Country}${obj["New Lv1-Lv2"]}`;
if (!res[key]) {
// 처음 등장한 객체라면 count: 0으로 초기화하여 저장
res[key] = { ...obj, count: 0 };
}
// 등장할 때마다 카운트 증가
res[key].count += 1;
});
// 저장소의 값들만 모아 새로운 배열로 반환
return Object.values(res);
};
console.log(convert(arr));실행 결과
콘솔에 출력되는 결과는 다음과 같습니다.
[
{ Country: 'BR', 'New Lv1-Lv2': '#N/A', count: 2 },
{ Country: '', 'New Lv1-Lv2': 'test', count: 1 }
]코드 설명
위 코드의 핵심 로직을 단계별로 살펴보면 다음과 같습니다.
1. 고유 키 생성: Country와 New Lv1-Lv2 속성 값을 문자열 템플릿 리터럴로 조합하여 각 객체의 고유 식별자 역할을 하는 키를 만듭니다.
2. 중복 확인 및 초기화: res 객체에 해당 키가 존재하지 않으면, 스프레드 연산자(...)를 사용해 원본 객체를 복사하고 count: 0을 추가하여 저장합니다.
3. 카운트 증가: 배열을 순회하는 동안 동일한 키를 가진 객체가 발견될 때마다 count 값을 1씩 증가시킵니다.
4. 결과 반환: 마지막으로 Object.values() 메서드를 사용해 저장소 객체에서 값들만 추출하여 최종 배열을 반환합니다.
이 방식은 시간 복잡도 O(n)으로 배열을 한 번만 순회하면 되기 때문에, 대량의 데이터를 처리할 때도 매우 효율적입니다. 또한 스프레드 연산자로 원본 객체를 복사하기 때문에 기존 데이터를 변경하지 않는 불변성(immutability)도 유지됩니다.