https://school.programmers.co.kr/learn/courses/30/lessons/42579
genreDic = {
classic : {
music : [각 장르에 담긴 고유번호 배열],
count : 각 장르의 재생수 합
},
pop : {
...
},
...
}
function solution(genres, plays) {
var answer = [];
const genreDic = {};
//genreDic의 각 장르별 music을 채운다.
genres.map((genre, idx) => {
if (!genreDic[genre]) {
genreDic[genre] = {
music: [idx],
count: 0,
};
} else {
genreDic[genre].music.push(idx);
}
});
//genreDic의 각 장르별 count를 채운다.
Object.entries(genreDic).map(([key, { music }]) => {
const count = music.reduce((acc, cur) => {
return acc + plays[cur];
}, 0);
genreDic[key].count = count;
});
//장르별 count로 정렬한 genreArr을 생성한다.
const genreArr = Object.keys(genreDic).sort(
(a, b) => +genreDic[b].count - +genreDic[a].count
);
//genreArr을 돌리면서 해당하는 장르의 곡들을 정렬, 2개씩 slice하고 answer에 push한다.
genreArr.map((genre) => {
const songs = genreDic[genre].music;
const arr = songs.sort((a, b) => {
return +plays[b] - +plays[a] || +a - +b;
});
answer.push(...arr.slice(0, 2));
});
return answer;
}
내 풀이는 뭔가 많이 추려냈는데도 조금 지저분했는데, 제출한 뒤 다른 사람의 풀이를 보니 깔끔한 코드가 있어서 올려 본다.
dic = {
classic : 각 장르의 재생수 합,
pop : 각 장르의 재생수 합,
...
}
{
genre : 곡의 장르,
count : 곡의 재생수,
index : 곡의 고유번호(인덱스)
}
function solution(genres, plays) {
var dic = {};
genres.forEach((t,i)=> {
dic[t] = dic[t] ? dic[t] + plays[i] :plays[i];
});
var dupDic = {};
return genres
.map((t,i)=> ({genre : t, count:plays[i] , index:i}))
.sort((a,b)=>{
if(a.genre !== b.genre) return dic[b.genre] - dic[a.genre];
if(a.count !== b.count) return b.count - a.count;
return a.index - b.index;
})
.filter(t=> {
if(dupDic[t.genre] >= 2) return false;
dupDic[t.genre] = dupDic[t.genre] ? dupDic[t.genre]+ 1 : 1;
return true;
})
.map(t=> t.index);
}
참고한 코드는... 우선 메소드 체이닝을 이용해서 간결하게 만든 게 깔끔해서 좋았고...
조금 복잡한 내 딕셔너리와 다르게 각 장르별 재생수 합만 넣어서 dic을 만들어 둔 후 나머지는 genres, plays에서 각자 가져와서 휘릭휘릭 계산한 점도 간단해서 좋았다.
또 filter를 저렇게 저런 식으로... index값을 활용하지 않고도 선착 n개만 받는 형식을 구현할 수 있다니 처음 보는 패턴이어서 새로웠다. 나중에 활용할 일이 있을 것 같다.