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

자바스크립트에서 배열의 동일한 값을 그룹화하는 방법

문자열이나 숫자 리터럴로 구성된 배열에 다음과 같이 중복된 값이 포함되어 있다고 가정해 보겠습니다.

const array = ['day', 'night', 'afternoon', 'night', 'noon', 'night', 'noon', 'day', 'afternoon', 'day', 'night'];

여기서 우리는 groupSimilar()라는 함수를 작성해야 합니다. 이 함수는 위와 같은 배열을 입력받아, 반복되는 요소들을 하위 배열의 첫 번째 요소로 묶고, 원본 배열에서 해당 값이 등장한 총 횟수를 두 번째 요소로 담은 새로운 배열을 반환해야 합니다.

따라서 위 예제의 경우 기대되는 출력 결과는 다음과 같습니다.

[
    [ 'day', 3 ],
    [ 'night', 4 ],
    [ 'afternoon', 2 ],
    [ 'noon', 2 ]
]

구현 예제

이제 이 함수의 코드를 직접 작성해 보겠습니다. 누산기를 활용해 새로운 배열을 구성하기 위해 Array.prototype.reduce() 메서드를 사용하고, 배열 내 반복되는 요소를 효율적으로 추적하기 위해 Map 객체를 함께 활용합니다.

const array = ['day', 'night', 'afternoon', 'night', 'noon', 'night',
'noon', 'day', 'afternoon', 'day', 'night'];
const groupSimilar = arr => {
    return arr.reduce((acc, val) => {
        const { data, map } = acc;
        const ind = map.get(val);
        if(map.has(val)){
            data[ind][1]++;
        } else {
            map.set(val, data.push([val, 1])-1);
        }
        return { data, map };
    }, {
        data: [],
        map: new Map()
    }).data;
};
console.log(groupSimilar(array));

동작 원리

이 코드의 핵심 로직은 다음과 같습니다.

  • data: 최종적으로 반환될 그룹화된 배열입니다. 각 요소는 [값, 개수] 형태의 하위 배열입니다.
  • map: 각 값이 data 배열의 몇 번째 인덱스에 저장되어 있는지 추적합니다. 덕분에 이미 등장한 값인지 확인할 때 전체 배열을 순회할 필요 없이 O(1) 시간 복잡도로 처리할 수 있습니다.
  • 배열을 순회하며 값이 처음 등장하면 data에 새 하위 배열을 추가하고 인덱스를 Map에 기록하고, 이미 존재하는 값이라면 해당 하위 배열의 카운트만 증가시킵니다.

출력 결과

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

[ [ 'day', 3 ], [ 'night', 4 ], [ 'afternoon', 2 ], [ 'noon', 2 ] ]

이처럼 reduce()Map을 조합하면 배열의 중복 값을 손쉽게 그룹화하면서 각 값의 출현 횟수까지 한 번의 순회로 계산할 수 있습니다.