Description
정수를 저장한 배열, arr에서 가장 작은 수를 제거한 배열을 리턴하는 함수, solution을 완성해주세요. 단, 리턴하려는 배열이 빈 배열인 경우엔 배열에 -1을 채워 리턴하세요. 예를 들어 arr이 [4,3,2,1]인 경우는 [4,3,2]를 리턴하고, [10] 면 [-1]을 리턴합니다.
Constraints
arr은 길이 1 이상인 배열입니다.
인덱스 i, j에 대해 i ≠ j이면 arr[i] ≠ arr[j] 입니다.
My Solution
처음엔 예시만 보고 "배열을 오름차순으로 정렬한 다음, 마지막 요소를 pop으로 제거하면 되겠다"라고 생각했는데, 더 생각해 보니 아니었다. 그렇게 되면 정렬된 배열이 나오게 되는데 정렬은 문제에 포함되지 않는다. 그래서 다른 방법을 써야 한다.
function solution(arr) {
arr.splice(arr.indexOf(Math.min(...arr)), 1);
return arr.length ? arr : [-1];
}
- 배열의 최솟값을 알아낼 때는 내장 함수인 Math.min()을 이용한다. 이때 Math.min은 배열이 아닌 숫자들의 목록을 인수로 받아야 한다. 배열 자체를 인수로 받을 순 없다. 그래서 전개 문법(Spread syntax)을 사용한다.
- 이렇게 얻어낸 최솟값의 인덱스를 arr.indexOf(최솟값)으로 찾아준다.
- splice를 통해 (시작 인덱스, 삭제 개수)를 인자로 넘겨 줘서 최솟값을 삭제해준다. splice는 원본을 변경한다.
- 이렇게 변경된 배열이 빈 배열이라면 [-1]을 리턴하고, 그렇지 않다면 변경된 배열을 리턴한다.
Other's Solution 1
function solution(arr) {
if (arr.length === 1) return [-1];
let min;
arr.reduce((acc, cur) => (min = cur > acc ? acc : cur));
return arr.filter(e => e !== min);
}
풀이 출처(블로그)
- array의 요소가 하나라면 [-1]을 반환하고 즉시 함수를 종료한다.
- reduce로 이전 값과 현재 값을 비교하여 가장 작은 수를 알아낸다.
- filter로 가장 작은 수를 제외한 나머지 수로 이루어진 배열을 만들어 반환한다.
reduce는 배열의 모든 요소의 합을 구할 때 유용하게 썼었는데, 이런 식으로 Math.min 내장 함수 대신 최솟값을 구할 때도 응용해서 쓸 수 있다는 것을 알았다. MDN에 보면 정말 많은 예제들과 활용법이 있는데, 배워 나가야겠다.
filter는 주어진 함수의 테스트를 통과하는 모든 요소를 모아서 새로운 배열로 반환해준다.
Other's Solution 2
function solution(arr) {
if (arr.length === 1 ) {
return [-1]
}
const minValue = Math.min.apply(null, arr)
const index = arr.findIndex(value => value === minValue)
arr.splice(index, 1)
return arr
}
이 풀이를 통해 apply, findIndex 메서드를 좀 더 공부할 수 있었다.
apply
apply는 주어진 this값과 배열로 제공되는 인자로 함수를 호출한다.
전개 문법 대신에 이런 방법으로 Math.min을 호출해서 동일한 결과를 얻어낼 수 있다.
apply는 call과 거의 동일한데 apply는 배열을 1개만 받아서 처리할 수 있지만, call은 여러 개의 배열을 받을 수 있다.
findIndex
findIndex는 주어진 판별 함수를 만족하는 배열의 첫 번째 요소에 대한 인덱스를 반환한다. 만족하는 요소가 없으면 -1을 반환한다.
여기서는 배열의 요소가 바로 윗줄에서 구했던 최솟값과 같은지에 대한 조건을 콜백 함수로 전달하고 있고, 이 조건이 만족되면 최솟값의 인덱스를 반환하도록 했다.
참고로 find는 인덱스 대신 값 자체를 반환한다.
간단한 알고리즘이지만 서로 다른 메서드를 사용해서 다양한 풀이가 나올 수 있다는 것을 알게 되었다. 풀었다고 끝이 아니라 다른 사람들의 풀이를 보면서 배워나가는 건 정말 필수적이라고 생각했다.
여기서만 해도 정말 많이 배워나갔다. spread syntax, Math.min, splice, indexOf, apply, findIndex, (+call, find), reduce, filter 등등. 아직 이런 것들을 깊게 안다고는 할 수 없어서, 더 많이 접해보면서 익숙하게 만들어야겠다.
참고 자료
https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Array/filter
https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce
https://ko.javascript.info/rest-parameters-spread
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/findIndex
https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Function/apply
'Algorithms > Programmers' 카테고리의 다른 글
[프로그래머스 Level 1] 정수 내림차순으로 배치하기 (자바스크립트) (0) | 2021.10.08 |
---|---|
[프로그래머스 Level 1] 콜라츠 추측 (자바스크립트) (0) | 2021.10.08 |
[프로그래머스 Level 1] 행렬의 덧셈 (자바스크립트) (0) | 2021.10.05 |
[프로그래머스 Level 1] 하샤드 수 (자바스크립트) (0) | 2021.10.05 |
[프로그래머스 Level 1] 직사각형 별찍기 (자바스크립트) (0) | 2021.10.05 |