본문으로 바로가기

프로젝트를 하며 금메달과 총 메달 수 만으로 정렬하는 것은 쉽게 구현하였습니다.

정렬 로직 (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를 부여받습니다.)

막상 지금 보면 간단한 로직인데 오랜 시간이 걸린 거 보니 알고리즘 공부를 더욱 더 열심히 해야겠습니다~