nums
는 숫자로 이루어진 배열입니다.
가장 자주 등장한 숫자를k
개수만큼 return해주세요.nums = [1,1,1,2,2,3], k = 2 return [1,2] // nums = [1] k = 1 return [1]
- 수정 전
function topK(nums, k) { const result = {}; nums.forEach((x) => { if (result[x]) { result[x] += 1 } else { result[x] = 0; result[x]++ }); // { '1': 2, '2': 3, '3': 6, '4': 1 } 값마다 중복 개수 확인 const sortable = [] // 빈 객체를 정의한 후 for (const key in result) { sortable.push([key, result[key]]) // key값과 value값으로 이루어진 배열값을 sortable에 push // [ [ '1', 2 ], [ '2', 3 ], [ '3', 6 ], [ '4', 1 ] ] } sortable.sort((a, b) => { return b[1] - a[1] // value값, 즉 작은 배열의 2번째 값을 기준으로 내림차순 정렬 // [ [ '3', 6 ], [ '2', 3 ], [ '1', 2 ], [ '4', 1 ] ] }) const totalResult = sortable.slice(0, k).map(element => Number(element[0])) return totalResult // k개수 만큼 자른 후 mapping으로 작은 배열의 첫번째값, 즉 해당하는 숫자 값을 출력 }; const arr = [2, 2, 2, 3, 3, 3, 3, 3, 1, 1, 3, 4]; topK(arr, 2) //[ 3, 2 ]
이틀 전 풀었던 해당 값의 중복 개수 구하기에서 약간 응용된 문제였다. 하지만 객체에서 key
값과 value
값으로 이루어진 배열을 만들기까지 굉장히 오래걸렸다. 특히 console.log
을 계속 찍어보느라 불필요하게 변수들을 계속적으로 생성했다. 다행히.. 도은님의 도움으로 Object.entries
메소드를 알게 되었다. 처음에 잘 이해가 가지 않아, 원리만 간단히 확인하고 위처럼 빈 배열을 생성한 후 일일이 push
해주는 방식으로 로직을 짰지만, Object.entries
을 적용하고 불필요한 변수들을 제거하니 아래처럼 로직을 줄일 수 있었다.
- 수정 후
function topK(nums, k) { const result = {}; nums.forEach((x) => { if (result[x]) { result[x] += 1 } else { result[x] = 0; result[x]++ }); // { '1': 2, '2': 3, '3': 6, '4': 1 } 값마다 중복 개수 확인 const sortable = Object.entries(result).sort((a,b)=>b[1] - a[1]).slice(0,k).map(element=>Number(element[0])) return sortable }; const arr = [2, 2, 2, 3, 3, 3, 3, 3, 1, 1, 3, 4]; topK(arr, 2) // [ 3, 2 ]
Object.entries(obj)
:[key,value]
과 같은 형태의 요소를 갖는 배열을 반환한다.const obj = {"a": 1, "b":2, "c": 3} Object.entries(obj) // [ [ 'a', 1 ], [ 'b', 2 ], [ 'c', 3 ] ]
Object.keys()
: 객체의key
값만으로 이루어진 배열을 반환한다.Object.keys(obj) // [ 'a', 'b', 'c' ]
Object.values()
: 객체의value
값만으로 이루어진 배열을 반환한다.Object.values(obj) // [ 1, 2, 3 ]