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

JavaScript로 여러 배열의 요소 순위(Rank) 매기는 방법

문제 소개

다음과 같이 숫자로 구성된 세 개의 JavaScript 배열이 있다고 가정해 보겠습니다.

const array1 = [10,23,53,74,33,56,6,0,43,45,11];
const array2 = [52,46,27,28,4,11,53,6,75,75,22];
const array3 = [26,18,10,12,31,12,5,8,44,34,65];

모든 배열의 길이는 항상 동일하며, 배열의 개수는 몇 개가 되더라도 상관없습니다.

이제 우리가 작성해야 할 함수는 여러 개의 배열을 입력받아, 같은 인덱스 위치에 있는 요소들을 서로 비교한 후 각 값의 순위(내림차순 기준)를 새로운 배열로 매핑하는 것입니다.

쉽게 말해, 첫 번째 인덱스에서는 세 배열의 첫 번째 요소끼리 비교해 가장 큰 값에 1위, 그다음 값에 2위, 가장 작은 값에 3위를 부여하고, 이 과정을 나머지 모든 인덱스에 대해 반복하는 방식입니다.

따라서 위 배열들에 대한 기대 출력은 다음과 같습니다.

const array1 = [3,2,1,1,1,1,2,3,2,2,3];
const array2 = [1,1,2,2,2,2,1,2,1,1,2];
const array3 = [2,3,3,3,3,3,3,1,2,3,1];

구현 코드

다음은 이 문제를 해결하는 전체 코드입니다.

const array1 = [10,23,53,74,33,56,6,0,43,45,11];
const array2 = [52,46,27,28,4,11,53,6,75,75,22];
const array3 = [26,18,10,12,31,12,5,8,44,34,65];

// 여러 배열을 인덱스별로 묶어주는 전치(transpose) 헬퍼 함수
const transpose = (rank, arr) => {
   return arr.map((el, ind) => {
      return [...(rank[ind] || []), el];
   });
};

// 각 그룹(같은 인덱스의 값 모음)에 대해 내림차순 순위를 계산하는 함수
const ranks = arr => {
   return arr.map(
      Map.prototype.get,
      [...arr]
      .sort((a, b) => b - a)
      .reduce((r => (m, v) => m.set(v, (r++, m.get(v)) || r))(0), new Map)
   );
};

// 순위 계산 후 결과를 원래 배열 구조로 복원하는 메인 함수
const findRanks = (...arrs) => {
   return arrs
   .reduce(transpose, [])
   .map(ranks)
   .reduce(transpose, []);
};
console.log(findRanks(array1, array2, array3));

코드 동작 원리

핵심 로직은 크게 세 단계로 구성됩니다.

1단계 − 전치(Transpose): reduce와 map을 활용해 여러 배열을 인덱스별로 재배열합니다. 예를 들어 첫 번째 그룹은 [10, 52, 26]처럼 같은 위치의 값들이 하나로 묶입니다.

2단계 − 순위 계산(Ranks): 각 그룹의 값을 내림차순으로 정렬한 뒤 Map 객체에 '값 → 순위' 형태로 저장하고, 원본 값에 대응하는 순위를 반환합니다. 값이 같으면 동일한 순위를 공유합니다.

3단계 − 재전치: 계산이 끝난 순위들을 다시 transpose를 통해 원래의 배열 구조로 되돌려 최종 결과를 완성합니다.

실행 결과

위 코드를 실행하면 콘솔에 다음과 같은 결과가 출력됩니다.

[
 [
   3, 2, 1, 1, 1,
   1, 2, 3, 3, 2,
   3
 ],
 [
   1, 1, 2, 2, 3,
   3, 1, 2, 1, 1,
   2
 ],
 [
   2, 3, 3, 3, 2,
   2, 3, 1, 2, 3,
   1
 ]
]