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

JavaScript에서 동일한 요소를 하위 배열로 그룹화하는 방법

배열 안에 중복된 값들이 섞여 있을 때, 같은 값을 가진 요소들을 하나의 하위 배열로 묶어서 새로운 배열을 반환하는 함수가 필요한 경우가 있습니다.

문제 정의

예를 들어 다음과 같은 숫자 배열이 있다고 가정해 보겠습니다.

const arr = [234, 65, 65, 2, 2, 234];

이때 동일한 값끼리 그룹화한 결과는 다음과 같아야 합니다.

const output = [[234, 234], [65, 65], [2, 2]];

해결 접근 방식

이 문제는 해시맵(객체)을 활용하면 효율적으로 해결할 수 있습니다. 해시맵에는 이미 등장한 각 값이 결과 배열 내 몇 번째 그룹에 속하는지 인덱스 정보를 저장합니다. 이후 for 루프로 배열을 순회하면서 다음 두 가지 경우로 나누어 처리합니다.

  • 이미 등장한 값인 경우: 해시맵에 저장된 인덱스를 참조하여 해당 그룹에 값을 추가(push)합니다.
  • 처음 등장한 값인 경우: 새로운 하위 배열을 생성하고, 그 그룹의 인덱스를 해시맵에 기록합니다.

구현 코드

다음은 위 로직을 구현한 전체 코드입니다.

const arr = [234, 65, 65, 2, 2, 234];

const groupArray = arr => {
    const map = {};
    const group = [];
    for(let i = 0; i < arr.length; i++){
        if(typeof map[arr[i]] === 'number'){
            // 이미 등장한 값이라면 해당 그룹에 추가
            group[map[arr[i]]].push(arr[i]);
        }else{
            // push 메서드는 배열의 새 길이를 반환하므로
            // 새로 추가된 요소의 인덱스는 length - 1
            map[arr[i]] = group.push([arr[i]]) - 1;
        }
    };
    return group;
}

console.log(groupArray(arr));

코드 설명

핵심 포인트는 group.push([arr[i]]) 부분입니다. JavaScript의 push() 메서드는 요소를 추가한 후 배열의 새로운 길이를 반환합니다. 따라서 새로 생성된 하위 배열의 실제 인덱스는 반환값에서 1을 빼면 됩니다. 이 값을 해시맵에 저장해두면, 이후 같은 값이 등장했을 때 O(1) 시간에 해당 그룹을 찾아 바로 추가할 수 있습니다.

실행 결과

위 코드를 실행하면 콘솔에 다음과 같은 출력이 나타납니다.

[ [ 234, 234 ], [ 65, 65 ], [ 2, 2 ] ]

정리

이 방식은 배열을 한 번만 순회하므로 시간 복잡도는 O(n)입니다. 객체(해시맵)를 활용해 각 값의 그룹 인덱스를 추적함으로써, 중복 요소를 효율적으로 하나의 하위 배열로 묶을 수 있습니다.