https://programmers.co.kr/learn/courses/30/lessons/42579
문제설명
스트리밍 사이트에서 장르 별로 가장 많이 재생된 노래를 두 개씩 모아 베스트 앨범을 출시하려 합니다. 노래는 고유 번호로 구분하며, 노래를 수록하는 기준은 다음과 같습니다.
1. 속한 노래가 많이 재생된 장르를 먼저 수록합니다.
2. 장르 내에서 많이 재생된 노래를 먼저 수록합니다.
3. 장르 내에서 재생 횟수가 같은 노래 중에서는 고유 번호가 낮은 노래를 먼저 수록합니다.
노래의 장르를 나타내는 문자열 배열 genres와 노래별 재생 횟수를 나타내는 정수 배열 plays가 주어질 때, 베스트 앨범에 들어갈 노래의 고유 번호를 순서대로 return 하도록 solution 함수를 완성하세요.
제한사항
- genres[i]는 고유번호가 i인 노래의 장르입니다.
- plays[i]는 고유번호가 i인 노래가 재생된 횟수입니다.
- genres와 plays의 길이는 같으며, 이는 1 이상 10,000 이하입니다.
- 장르 종류는 100개 미만입니다.
- 장르에 속한 곡이 하나라면, 하나의 곡만 선택합니다.
- 모든 장르는 재생된 횟수가 다릅니다.
입출력 예
접근방법
주어진 값들로 데이터묶음을 만들어서 푸는 방식을 생각해봤다.
1. map 자료구조를 사용해 { genre , [key인 genre에 해당하는 plays의 값들의 배열]} 처럼 데이터를 묶어서 풀고자 했다.
하지만 plays의 값들의 index에 대한 정보도 같이 고려해줘야 하기때문에 이러한 접근방식으로는 풀 수 없다.
2. 다른 방법은, 객체로 값들을 관리하는 것이다.
객체에 index에 대한 정보도 같이 담아 {index, genre, playCount} 이 세값을 가진 객체들을 배열로 관리하는 방식으로 풀어봤다.
자세한 설명은 주석을 참고해주세요
function solution(genres, plays) {
// ①
// 인수로 주어진 값들을 하나의 객체로 묶는 처리
// index값이 중요하기 때문에 index도 같이 객체에 담아준다
let genreInfoArr = genres.map((genre, index) => ({index, genre, playCount:plays[index]}))
// ②
// 장르 내에서 많이 재생된 노래순으로 출력해야하기 때문에
// 어느 장르가 가장 많이 재생됐는지 찾아야 한다.
// { genre, totalPlayCount } 정보를 담은 객체가 배열에 저장될 것이다.
let genrePlayCount = [];
// ①에서 정리한 값들을 map메서드를 사용해 한번씩 순회한다.
genreInfoArr.map((genreInfo)=>{
// genrePlayCount 배열에 이미 만들어진 장르객체가 있는지 확인하기 위한 코드
// 만약 genrePlayCount 배열에 장르객체가 있다면 thisGenre변수에는, genreInfo와 장르가 같은 장르객체가 반환될 것 이다.
const thisGenre = genrePlayCount.find(genrePlay => genrePlay.genre === genreInfo.genre);
if(thisGenre){
//이미 만들어진 장르객체의 totalPlayCount값에 genreInfo의 playCount값을 더해준다.
thisGenre.totalPlayCount += genreInfo.playCount;
}else{
// thisGenre가 없다면 genre와 playCount의 정보를 가진 객체를 push해준다.
genrePlayCount.push({ genre : genreInfo.genre, totalPlayCount : genreInfo.playCount });
}
});
// ③ 많이 재생된 장르 순서대로 정렬해준다.
genrePlayCount = genrePlayCount.sort((a, b) => b.totalPlayCount - a.totalPlayCount);
//④ genrePlayCount 배열을 순회하면서 answer배열에 인덱스를 넣어줄건데
const answer = [];
genrePlayCount.map((targetGenre) => {
// 우선 targetGenre와 일치하는 genre를 가진 객체를 thisGenreSongs에 반환받는다
let thisGenreSongs = genreInfoArr.filter((genreInfo)=>genreInfo.genre === targetGenre.genre);
// 그리고 많이 재생된 순서를 알아야하기 때문에 thisGenreSongs를 playCount기준으로 내림차순 정렬한다.
thisGenreSongs.sort((a, b)=> b.playCount - a.playCount);
// 노래의 index를 answer에 push한다.
answer.push(thisGenreSongs[0].index);
if(thisGenreSongs.length > 1){
answer.push(thisGenreSongs[1].index);
}
})
return answer;
}
정말 어려운문제다..ㅜㅠ
여러번 풀어봐야겠다