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

JavaScript에서 다른 문자열 배열의 순서를 기준으로 객체 배열 정렬하는 방법

JavaScript 개발을 하다 보면 객체 배열을 특정 기준에 따라 재정렬해야 하는 경우가 자주 발생합니다. 이번 글에서는 별도의 문자열 배열에 정의된 순서를 참조하여 객체 배열을 정렬하는 방법을 예제와 함께 살펴보겠습니다.

문제 상황

먼저 다음과 같이 id 속성을 기준으로 정렬된 객체 배열이 있다고 가정해 보겠습니다.

const unordered = [{
    id: 1,
    string: 'sometimes'
}, {
    id: 2,
    string: 'be'
}, {
    id: 3,
    string: 'can'
}, {
    id: 4,
    string: 'life'
}, {
    id: 5,
    string: 'tough'
}, {
    id: 6,
    string: 'very'
}];

그리고 우리가 원하는 최종 순서를 담고 있는 다음과 같은 문자열 배열이 하나 더 있습니다.

const ordered = ['Life', 'sometimes', 'can', 'be', 'very', 'tough'];

목표는 첫 번째 배열을 정렬하여 각 객체의 string 속성 값이 두 번째 배열(ordered)에 나타나는 순서와 동일하게 배치되도록 만드는 것입니다.

해결 방법: sort()와 indexOf() 활용

JavaScript의 Array.prototype.sort() 메서드는 비교 함수를 인자로 받습니다. 이 비교 함수 내부에서 각 객체의 string 값이 ordered 배열에서 몇 번째 인덱스에 위치하는지 indexOf()로 확인한 뒤, 그 차이를 반환하면 됩니다.

예제 코드

const unordered = [{
    id: 1,
    string: 'sometimes'
}, {
    id: 2,
    string: 'be'
}, {
    id: 3,
    string: 'can'
}, {
    id: 4,
    string: 'life'
}, {
    id: 5,
    string: 'tough'
}, {
    id: 6,
    string: 'very'
}];

const ordered = ['Life', 'sometimes', 'can', 'be', 'very', 'tough'];

const sorter = (a, b) => {
    return ordered.indexOf(a.string) - ordered.indexOf(b.string);
};

unordered.sort(sorter);
console.log(unordered);

실행 결과

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

[
    { id: 4, string: 'life' },
    { id: 1, string: 'sometimes' },
    { id: 3, string: 'can' },
    { id: 2, string: 'be' },
    { id: 6, string: 'very' },
    { id: 5, string: 'tough' }
]

코드 동작 원리

비교 함수 sorter는 두 객체 abstring 값을 ordered 배열에서 찾아 각각의 인덱스를 구합니다. 그 차이가 음수이면 a가 앞에, 양수이면 b가 앞에 오도록 정렬됩니다. 결국 ordered 배열에서 먼저 등장하는 단어일수록 앞쪽에 배치되는 것입니다.

주의 사항 및 성능 최적화

대소문자 처리: 위 예제에서 'life''Life'처럼 대소문자가 일치하지 않으면 indexOf()-1을 반환하여 의도대로 정렬되지 않을 수 있습니다. 대소문자를 구분하지 않으려면 비교 전에 toLowerCase()로 문자열을 통일하는 것이 안전합니다.

성능 개선: indexOf()는 호출될 때마다 선형 탐색(O(n))을 수행하므로, 배열의 크기가 커지면 정렬 성능이 저하될 수 있습니다. 이 경우 Map 객체에 미리 인덱스를 저장해 두면 O(1) 시간 복잡도로 조회할 수 있어 훨씬 효율적입니다.

const indexMap = new Map(
    ordered.map((str, i) => [str.toLowerCase(), i])
);

unordered.sort(
    (a, b) => indexMap.get(a.string.toLowerCase()) - indexMap.get(b.string.toLowerCase())
);

이처럼 sort() 메서드에 적절한 비교 함수만 제공하면, 어떤 사용자 지정 순서로든 배열을 손쉽게 정렬할 수 있습니다.