프로젝트를 하며 금메달과 총 메달 수 만으로 정렬하는 것은 쉽게 구현하였습니다.
정렬 로직 (sortByMode)
sortByMode 함수는 주어진 mode에 따라 메달 데이터를 정렬하는 역할을 합니다. 여기서 사용되는 주요 정렬 기준은 두 가지입니다. 금메달 순과 총 메달 수 순입니다.
const sortByMode = (medalList, mode) => {
return [...medalList].sort((a, b) => {
if (mode === 'sortByGold') {
if (b.gold !== a.gold) {
return b.gold - a.gold;
} else {
if (b.silver !== a.silver) {
return b.silver - a.silver;
} else if (b.bronze !== a.bronze) {
return b.bronze - a.bronze;
} else {
return a.country.localeCompare(b.country);
}
}
} else if (mode === 'sortByTotal') {
const totalA = a.gold + a.silver + a.bronze;
const totalB = b.gold + b.silver + b.bronze;
if (totalB !== totalA) {
return totalB - totalA;
} else {
if (b.gold !== a.gold) {
return b.gold - a.gold;
} else if (b.silver !== a.silver) {
return b.silver - a.silver;
} else if (b.bronze !== a.bronze) {
return b.bronze - a.bronze;
} else {
return a.country.localeCompare(b.country);
}
}
}
return 0;
});
};
- 금메달 기준으로 정렬 (mode === 'sortByGold'):
- 금메달 수가 다른 두 국가를 비교하여 내림차순으로 정렬합니다.
- 금메달 수가 같으면, 은메달 수를 비교하고, 그 다음으로 동메달 수를 비교합니다.
- 만약 모든 메달 수가 같다면, 한글 순으로 국가명을 정렬합니다.
- 총 메달 수 기준으로 정렬 (mode === 'sortByTotal'):
- 각 국가의 금, 은, 동메달을 합산하여 총 메달 수를 구합니다.
- 총 메달 수가 다르면, 내림차순으로 정렬합니다.
- 총 메달 수가 같으면, 금메달, 은메달, 동메달 순으로 비교하고, 그 후 국가명을 한글 순으로 정렬합니다.
그런데 순위를 매길 때 난관에 부딛혔습니다. 순위를 매길 때는 동률을 어떻게 처리할 지가 중요한데, 예를 들어 세 국가가 동일한 금메달 수를 가질 경우 이 세 국가에는 1등을 부여해야 하고, 그 다음 순위의 국가에는 4등을 부여하는 것으로 정하였습니다.
순위 매기기 로직 (sortByRank)
이미 정렬되어진 메달 리스트에 순위를 부여해주는 로직입니다.
const sortByRank = (sortedMedals, mode) => {
let rank = 1;
let rankSkip = 0;
let prevMedals = null;
return sortedMedals.map((m, index) => {
if (mode === 'sortByGold') {
if (index === 0 || (prevMedals && prevMedals.gold === m.gold)) {
m.rank = rank;
rankSkip++;
} else {
rank += rankSkip;
m.rank = rank;
rankSkip = 1;
}
prevMedals = { gold: m.gold, silver: m.silver, bronze: m.bronze };
} else if (mode === 'sortByTotal') {
if (
index === 0 ||
(prevMedals && prevMedals.gold + prevMedals.silver + prevMedals.bronze === m.gold + m.silver + m.bronze)
) {
m.rank = rank;
rankSkip++;
} else {
rank += rankSkip;
m.rank = rank;
rankSkip = 1;
}
prevMedals = { gold: m.gold, silver: m.silver, bronze: m.bronze };
}
return m;
});
};
동률 처리:
- 동률인 국가들은 같은 순위를 부여받습니다. (기존의 rank를 부여받습니다.)
- 그 뒤에 오는 국가들은 동률 수만큼 순위를 건너뛰고 다음 순위를 부여받습니다. (누적된 rankSkip만큼을 더한 rank를 부여받습니다.)
막상 지금 보면 간단한 로직인데 오랜 시간이 걸린 거 보니 알고리즘 공부를 더욱 더 열심히 해야겠습니다~