53.3/100
genres라는 1차원배열과 plays라는 1차원배열이 존재하며
이때, 각 장르마다의 총합플레이시간이 가장큰 장르를 기준으로 2개씩 뽑아낸다. (1개밖에 없을경우 1개만 가능)
for(let i=0;i<plays.length;i++)
{
if(total[genres[i]] === undefined){
total[genres[i]] = plays[i];
}
else
total[genres[i]] += plays[i];
}
해당 이름의 장르 프로퍼티가 없다면 plays값을 넣고 그게 아니라면 값을 더해준다.
var dic = {}; //이부분 존나중요하니 기억해 설정안하면 에러떠
genres.forEach((t,i)=> {
dic[t] = dic[t] ? dic[t] + plays[i] :plays[i];
});
간단한 삼항연산자로 존재한다면 더한값을쓰고 아니라면 처음 plays값을 넣는다.
genres.map((t,i)=> ({genre : t, count:plays[i] , index:i}))
ex) ["classic", "pop", "classic", "classic", "pop"], [500, 600, 150, 800, 2500]
라면 해당 내용은
{ genre: 'classic', count: 500, index: 0 }
{ genre: 'pop', count: 600, index: 1 }
{ genre: 'classic', count: 150, index: 2 }
{ genre: 'classic', count: 800, index: 3 }
{ genre: 'pop', count: 2500, index: 4 }
이러한 형태로 존재
중요한 점 : 리턴되는 {}부분이 ()로 묶여있어야한다.!!!
배열안의 객체에도 적용이 가능하다. (각각의 객체를 하나의 세트로 본다.)
ex)
let saveArray = [
{ genre: 'pop', count: 600, index: 1 },
{ genre: 'pop', count: 2500, index: 4 },
{ genre: 'classic', count: 500, index: 0 },
{ genre: 'classic', count: 150, index: 2 },
{ genre: 'classic', count: 800, index: 3 },
{ genre: 'magic', count: 1000, index: 5 }
];
let dic = { classic: 1450, pop: 3100 ,magic:1000};
console.log(saveArray.sort((a,b)=>a.count -b.count)); //(1)
console.log(saveArray.sort((a,b)=>dic[a.genre] -dic[b.genre])); //(2)
count에 따라
오름차순
으로 배열이 정렬된다.
[
{ genre: 'classic', count: 150, index: 2 },
{ genre: 'classic', count: 500, index: 0 },
{ genre: 'pop', count: 600, index: 1 },
{ genre: 'classic', count: 800, index: 3 },
{ genre: 'magic', count: 1000, index: 5 },
{ genre: 'pop', count: 2500, index: 4 }
]
dic배열안의 프로퍼티 값에 따라
오름차순
으로 배열이 정렬된다.
[
{ genre: 'magic', count: 1000, index: 5 },
{ genre: 'classic', count: 150, index: 2 },
{ genre: 'classic', count: 500, index: 0 },
{ genre: 'classic', count: 800, index: 3 },
{ genre: 'pop', count: 600, index: 1 },
{ genre: 'pop', count: 2500, index: 4 }
]
따라서 sort 함수는 필요에따라 배열안에 객체형태의 틀에도 적용되어 해당 값을 비교하여 오름차순을 원하면 sort((a,b)=> a.대상 - b.대상) 과 같은 형태로 하고
내림차순을 원하면 sort((a,b) => b.대상 - a.대상) 과 같은 형태를 쓴다.
.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;
})
위와같은 형태로 기준은 장르가 가장많이 재생된것을 먼저 기준을 잡고 그 후는 해당 장르에서 count가 가장 많이된 것을 고르게 한다. (내림차순 즉,b - a 형태)
let saveArray = [
{ genre: 'pop', count: 600, index: 1 },
{ genre: 'pop', count: 2500, index: 4 },
{ genre: 'classic', count: 500, index: 0 },
{ genre: 'classic', count: 150, index: 2 },
{ genre: 'classic', count: 800, index: 3 },
{ genre: 'magic', count: 1000, index: 5 }
];
let dic = { classic: 1450, pop: 3100 ,magic:1000};
console.log(saveArray.filter((t)=> {
if(t.genre == 'pop')
return false;
else
return true;
}))
특정 내용에 따라 true를 리턴하면 정상값을 리턴하고 false를 리턴하면 해당 값을 리턴하지 않는다.
console.log 결과
[
{ genre: 'classic', count: 500, index: 0 },
{ genre: 'classic', count: 150, index: 2 },
{ genre: 'classic', count: 800, index: 3 },
{ genre: 'magic', count: 1000, index: 5 }
]
.filter(t=> {
if(dupDic[t.genre] >= 2) return false;
dupDic[t.genre] = dupDic[t.genre] ? dupDic[t.genre]+ 1 : 1;
return true;
})
가져온 배열형태의 객체의 프로퍼티가 없다면 생성하고 1을 추가하고 있다면 해당 프로퍼티 값에 1을 추가하는 형태를 진행하면서 해당 프로퍼티 값이 2보다 크다면 그 후 내용은 return false를 통해 반환하지 않는 역할을 한다.
.map(t=> t.index);
해당 배열형태의 객체의 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;
})
.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);
}
중요부분 : sort나 filter를 배열안의 객체에 적용할수있고 해당 프로퍼티 값에 sort를 적용하여 처리하면 오름차순 혹은 내림차순 처리가 가능하면서 해당 객체가 세트로 전부 적용되는 형태가 된다.
function solution(genres, plays) {
const genreMap = new Map();
genres.map((genre,idx)=>[genre,plays[idx]])
.map(([genre,play],idx)=>{
const data = genreMap.get(genre) || {total:0 , songs:[]};
genreMap.set(genre,{
total : data.total + play,
songs : [...data.songs,{play,idx}]
.sort((a,b)=>b.play-a.play)
.slice(0,2)
})
})
return [...genreMap.entries()]
.sort((a,b)=>b[1].total - a[1].total)
.flatMap(item => item[1].songs)
.map(song=>song.idx)
}
const genreMap = new Map();
genres.map((genre,idx)=>[genre,plays[idx]])
.map(([genre,play],idx)=>{
const data = genreMap.get(genre) || {total:0 , songs:[]}; //1.
genreMap.set(genre,{
total : data.total + play, //2.
songs : [...data.songs,{play,idx}]
.sort((a,b)=>b.play-a.play)
.slice(0,2) //3.
})
})
- 각각의 genre와 play마다 기존에 genreMap에 genre가 없을 경우
{total:0 , songs:[]}
로 처리를 진행하고 만약 있을경우genreMap.get(genre)
로 추가하여 처리한다.- total은 기존값에 play를 추가한다.
- songs는 기존의
{play, idx}
인 data.songs에 새로운{play, idx}
를 추가한 것을 정렬하고 2개만 잘라낸다.
return [...genreMap.entries()] //1.
.sort((a,b)=>b[1].total - a[1].total) //2.
.flatMap(item => item[1].songs) //3.
.map(song=>song.idx) //4.
- 객체의 경우 sort를 못하므로 {} 형태를 []로 바꿔준다.
- 속한 노래가 많이 재생된 장르를 위한 sort를 하고
- 분리한 부분의 songs를 참고하고
- songs의 idx를 참고해서 리턴한다.