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

JavaScript 두 배열 매칭하기: 이름 배열로 UID 배열 만들기

문제 상황

두 개의 배열이 있다고 가정해 보겠습니다. 하나는 사용자 정보를 담은 객체 배열이고, 다른 하나는 사용자 이름 문자열 배열입니다.

const data = [{
    name: 'Kamlesh Kapasi',
    uid: 123
}, {
    name: 'Mahesh Babu',
    uid: 129
}, {
    name: 'Akshay Kapoor',
    uid: 223
}, {
    name: 'Vikas Gupta',
    uid: 423
}, {
    name: 'Mohit Dalal',
    uid: 133
}, {
    name: 'Rajkumar Hirani',
    uid: 233
}, {
    name: 'Joy',
    uid: 127
}];
const names = ['Joy', 'Rajkumar Hirani', 'Akshay Kapoor', 'Mahesh Babu',
'Mohit Dalal', 'Kamlesh Kapasi', 'Vikas Gupta']

여기서 해야 할 작업은 names 배열을 순회하면서, 각 이름에 해당하는 uidnames 배열과 동일한 순서로 담은 숫자 배열을 만드는 함수를 작성하는 것입니다. 즉, 이름 배열의 순서를 그대로 유지하면서 이름을 고유 ID로 변환하는 것이 목표입니다.

해결 방법: reduce와 findIndex 활용

이 문제는 Array.prototype.reduce()Array.prototype.findIndex() 메서드를 조합하면 깔끔하게 해결할 수 있습니다. reduce는 결과 배열을 누적하는 역할을 하고, findIndex는 객체 배열에서 해당 이름을 가진 요소의 위치를 찾아줍니다.

const data = [{
    name: 'Kamlesh Kapasi',
    uid: 123
}, {
    name: 'Mahesh Babu',
    uid: 129
}, {
    name: 'Akshay Kapoor',
    uid: 223
}, {
    name: 'Vikas Gupta',
    uid: 423
}, {
    name: 'Mohit Dalal',
    uid: 133
}, {
    name: 'Rajkumar Hirani',
    uid: 233
}, {
    name: 'Joy',
    uid: 127
}];
const names = ['Joy', 'Rajkumar Hirani', 'Akshay Kapoor', 'Mahesh Babu',
'Mohit Dalal', 'Kamlesh Kapasi', 'Vikas Gupta']
const mapId = (arr, names) => {
    return names.reduce((acc, val) => {
        const index = arr.findIndex(el => el.name === val);
        return acc.concat(arr[index].uid);
    }, []);
}
console.log(mapId(data, names));

코드 동작 원리

mapId 함수의 내부 로직을 단계별로 살펴보면 다음과 같습니다.

  1. names.reduce()를 호출하며 초기값으로 빈 배열 []을 전달합니다.
  2. 각 이름(val)에 대해 findIndex를 실행하여 data 배열 내에서 일치하는 name 속성을 가진 객체의 인덱스를 찾습니다.
  3. 찾은 인덱스로 해당 객체의 uid 값을 꺼내 누적 배열(acc)에 concat으로 추가합니다.
  4. 모든 이름에 대해 반복이 끝나면, names 배열 순서대로 정렬된 uid 배열이 최종 반환됩니다.

실행 결과

위 코드를 콘솔에서 실행하면 다음과 같은 출력을 확인할 수 있습니다.

[
    127, 233, 223,
    129, 133, 123,
    423
]

출력 결과를 보면 입력된 names 배열의 순서('Joy' → 'Rajkumar Hirani' → ...)와 정확히 일치하는 순서로 uid 값들이 배치되어 있는 것을 알 수 있습니다.

참고: 성능 개선 팁

현재 구현은 이름마다 findIndex를 호출하므로 시간 복잡도가 O(n×m)입니다. 데이터 양이 많다면 먼저 data 배열을 Map 또는 객체로 변환해 이름을 키로 조회하면 O(n+m)으로 최적화할 수 있습니다.

const mapIdOptimized = (arr, names) => {
    const lookup = new Map(arr.map(el => [el.name, el.uid]));
    return names.map(name => lookup.get(name));
}

이처럼 JavaScript의 배열 메서드를 적절히 조합하면 두 배열 간의 데이터 매칭 작업을 간결하고 효율적으로 처리할 수 있습니다.