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

JavaScript로 중복 값이 있는 배열을 등장 횟수를 담은 객체 배열로 변환하는 방법

문제 상황

다음과 같이 중복된 항목이 포함된 문자열 배열이 있다고 가정해 보겠습니다.

const arr = ['California','Texas','Texas','Texas','New York','Missouri','New Mexico','California'];

여기서 우리가 작성해야 할 것은 이러한 배열을 입력으로 받아, 고유한 항목마다 하나의 객체를 생성하고 각 객체에 원본 배열에서의 등장 횟수를 담은 count 속성을 포함시킨 객체 배열을 반환하는 JavaScript 함수입니다.

따라서 위 배열에 대한 최종 출력 결과는 다음과 같은 형태가 됩니다.

const output = [
    {'name':'California', 'count':2},
    {'name':'Texas', 'count':3},
    {'name':'New York', 'count':1},
    {'name':'Missouri', 'count':1},
    {'name':'New Mexico', 'count':1},
];

예제 코드

이를 구현한 코드는 다음과 같습니다.

const arr = ['California','Texas','Texas','Texas','New York','Missouri','New Mexico','California'];
const findOccurrences = (arr = []) => {
    const res = [];
    arr.forEach(el => {
        const index = res.findIndex(obj => {
            return obj['name'] === el;
        });
        if(index === -1){
            res.push({
                "name": el,
                "count": 1
            })
        }
        else{
            res[index]["count"]++;
        };
    });
    return res;
};
console.log(findOccurrences(arr));

코드 동작 원리

이 코드의 동작 방식을 단계별로 살펴보면 다음과 같습니다.

  • 결과 배열 초기화: 최종 결과를 저장할 빈 배열 res를 생성합니다.
  • 배열 순회: forEach 메서드로 원본 배열의 각 요소를 하나씩 확인합니다.
  • 기존 항목 검색: findIndex를 사용해 결과 배열에 이미 동일한 값의 객체가 존재하는지 찾습니다.
  • 조건 분기: 존재하지 않으면(index === -1) count가 1인 새 객체를 추가하고, 이미 존재하면 해당 객체의 count 값을 1 증가시킵니다.

실행 결과

콘솔에 출력되는 결과는 다음과 같습니다.

[
    { name: 'California', count: 2 },
    { name: 'Texas', count: 3 },
    { name: 'New York', count: 1 },
    { name: 'Missouri', count: 1 },
    { name: 'New Mexico', count: 1 }
]

참고: 더 효율적인 대안

위 방식은 각 요소마다 findIndex로 결과 배열 전체를 탐색하므로 시간 복잡도가 O(n²)입니다. 데이터 양이 많다면 Map을 해시 맵처럼 활용해 O(n)까지 성능을 개선할 수 있습니다.

const findOccurrences = (arr = []) => {
    const map = new Map();
    arr.forEach(el => {
        map.set(el, (map.get(el) || 0) + 1);
    });
    return Array.from(map, ([name, count]) => ({ name, count }));
};

Map은 삽입 순서를 유지하기 때문에 첫 번째 예제와 동일한 순서의 결과를 얻을 수 있으며, 대량의 데이터를 처리할 때 훨씬 빠른 성능을 보입니다.