배열에 담긴 객체들 중에서 중복된 객체를 제거하고, 중복이 없는 새로운 배열을 반환하는 함수를 작성해야 하는 경우가 종종 있습니다. 이때 두 객체가 키(key)의 개수가 같고, 키의 이름이 동일하며, 각 키에 대응하는 값까지 모두 일치할 때 서로 중복된 것으로 판단합니다.
해결 방법
가장 간단하고 직관적인 방법은 JSON.stringify()를 활용하는 것입니다. 각 객체를 문자열로 직렬화한 뒤 이를 맵(map)의 키로 사용하여 이미 등장한 객체인지 확인합니다. 처음 보는 객체라면 새 배열에 추가하고, 이미 존재하는 객체라면 건너뛰는 방식입니다.
예제 코드
const arr = [
{
"timestamp": 564328370007,
"message": "It will rain today"
},
{
"timestamp": 164328302520,
"message": "will it rain today"
},
{
"timestamp": 564328370007,
"message": "It will rain today"
},
{
"timestamp": 564328370007,
"message": "It will rain today"
}
];
const map = {};
const newArray = [];
arr.forEach(el => {
if (!map[JSON.stringify(el)]) {
map[JSON.stringify(el)] = true;
newArray.push(el);
}
});
console.log(newArray);실행 결과
콘솔에는 다음과 같이 중복이 제거된 배열이 출력됩니다.
[
{ timestamp: 564328370007, message: 'It will rain today' },
{ timestamp: 164328302520, message: 'will it rain today' }
]코드 설명
위 코드의 동작 원리를 단계별로 살펴보면 다음과 같습니다.
- 직렬화:
JSON.stringify(el)를 통해 각 객체를 고유한 문자열로 변환합니다. 내용이 완전히 같은 객체는 항상 동일한 문자열이 되므로 비교 기준으로 삼을 수 있습니다. - 중복 검사: 맵(
map)에 해당 문자열이 키로 존재하지 않으면, 아직 등장하지 않은 객체라는 의미입니다. - 결과 수집: 새로운 객체일 경우 맵에 표시를 남기고
newArray에 원본 객체를 그대로 push하여 참조와 데이터 구조를 유지합니다.
주의할 점
이 방식은 간편하지만 몇 가지 한계도 있습니다. JSON.stringify()는 객체 내 키의 순서에 따라 다른 문자열을 생성할 수 있으므로, 키 순서만 다른 객체는 중복으로 인식되지 않을 수 있습니다. 또한 함수나 undefined, 심볼(Symbol) 같은 값은 직렬화 과정에서 손실됩니다. 이런 경우에는 객체의 키를 미리 정렬하거나, 특정 필드(예: timestamp)를 기준으로 중복을 판별하는 방식을 고려하는 것이 좋습니다.