문제 상황
두 개의 배열이 있다고 가정해 보겠습니다. 하나는 사용자 정보를 담은 객체 배열이고, 다른 하나는 사용자 이름 문자열 배열입니다.
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 배열을 순회하면서, 각 이름에 해당하는 uid를 names 배열과 동일한 순서로 담은 숫자 배열을 만드는 함수를 작성하는 것입니다. 즉, 이름 배열의 순서를 그대로 유지하면서 이름을 고유 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 함수의 내부 로직을 단계별로 살펴보면 다음과 같습니다.
names.reduce()를 호출하며 초기값으로 빈 배열[]을 전달합니다.- 각 이름(
val)에 대해findIndex를 실행하여data배열 내에서 일치하는name속성을 가진 객체의 인덱스를 찾습니다. - 찾은 인덱스로 해당 객체의
uid값을 꺼내 누적 배열(acc)에concat으로 추가합니다. - 모든 이름에 대해 반복이 끝나면, 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의 배열 메서드를 적절히 조합하면 두 배열 간의 데이터 매칭 작업을 간결하고 효율적으로 처리할 수 있습니다.