[JS] 프로그래머스 코딩테스트 연습 | 해시 - 베스트 앨범

zaman·2022년 3월 1일
0

Coding test | Progranmmers

목록 보기
18/40
post-thumbnail

문제링크: 해시 > 베스크앨범

1. 문제

스트리밍 사이트에서 장르 별로 가장 많이 재생된 노래를 두 개씩 모아 베스트 앨범을 출시하려 합니다. 노래는 고유 번호로 구분하며, 노래를 수록하는 기준은 다음과 같습니다.

  1. 속한 노래가 많이 재생된 장르를 먼저 수록합니다.
  2. 장르 내에서 많이 재생된 노래를 먼저 수록합니다.
  3. 장르 내에서 재생 횟수가 같은 노래 중에서는 고유 번호가 낮은 노래를 먼저 수록합니다.

노래의 장르를 나타내는 문자열 배열 genres와 노래별 재생 횟수를 나타내는 정수 배열 plays가 주어질 때, 베스트 앨범에 들어갈 노래의 고유 번호를 순서대로 return 하도록 solution 함수를 완성하세요.

2. 입출력 예




3. 풀이

function solution(genres, plays) {
  let table = new Map();
  const genre = genres.map((v, i) => [v, plays[i]]);

  genre.forEach(([genre, play], index) => {
     // table에 장르가 있다면 그걸 가져오고 없으면 초기값
    const data = table.get(genre) || { total: 0, songs: [] };
    table.set(genre, {
      total: data.total + play,
      songs: [
        ...data.songs, // 기존 값을 복사
        {
          play, // 추가할 오브젝트 : 재생횟수, 인덱스
          index,
        },
      ]
        .sort((a, b) => b.play - a.play) // play 기준 내림차순으로 정렬
        .slice(0, 2), // top 2만 slice
    });
  });

  return [...table.entries()] // [key, value ]
    .sort((a, b) => b[1].total - a[1].total) // 총 재생수를 기준으로 내림차
    .flatMap((item) => item[1].songs)
    .map((song) => song.index);
}
  1. [장르, 재생 수]가 담긴 genre라는 배열을 만들어준다.
[
  [ 'classic', 500 ],
  [ 'pop', 600 ],
  [ 'classic', 150 ],
  [ 'classic', 800 ],
  [ 'pop', 2500 ]
]
  1. genre에 forEach를 해준다. (forEach는 각 배열 요소에 제공된 함수를 한 번 씩 실행해줌)
  • data는 table(map)에 genre가 키 값으로 있으면 키 값, 없다면 { total:0, songs: [] }을 초기값으로 한다
  • table.set으로 total은 각 장르의 재생 수 합을, songs에는 재생수, 인덱스가 들어가게 만든다
  • songs는 play를 기준으로 내림차순으로 정렬하고 slice해준다(top 2만 필요)
  • Object.entries()
    이 Object.entries()메서드는 주어진 개체의 고유한 열거 가능한 문자열 키 속성 [key, value]쌍의 배열을 반환합니다. 이것은 루프 가 프로토타입 체인의 속성도 열거 for...in한다는 점을 제외하고 루프를 사용하여 반복하는 것과 동일합니다.for...in (mdn)
  • 재생수를 기준으로 오름차( 총 재생 수가 많은게 먼저 수록됨)
  • Array.prototype.flatMap() ( = flat() + map() )
    flatMap() 메서드는 먼저 매핑함수를 사용해 각 엘리먼트에 대해 map 수행 후, 결과를 새로운 배열로 평탄화합니다. 이는 깊이 1의 flat 이 뒤따르는 map 과 동일하지만, flatMap 은 아주 유용하며 둘을 하나의 메소드로 병합할 때 조금 더 효율적입니다. (mdn)
[
  { play: 2500, index: 4 },
  { play: 600, index: 1 },
  { play: 800, index: 3 },
  { play: 500, index: 0 }
]
  • map으로 songs에서 인덱스 값만 가지는 배열을 만듦
  • 마지막으로 값을 반환해주면 끝이다
profile
개발자로 성장하기 위한 아카이브 😎

0개의 댓글