[JavaScript] - Math.min, Math.max, apply 함수

Minji Kim·2022년 9월 14일
0
post-thumbnail

프로그래머스 Lv.1 제일 작은 수 제거하기 문제를 풀며 정리한 내용입니다.

문제

문제 설명

정수를 저장한 배열, arr 에서 가장 작은 수를 제거한 배열을 리턴하는 함수, solution을 완성해주세요. 단, 리턴하려는 배열이 빈 배열인 경우엔 배열에 -1을 채워 리턴하세요. 예를들어 arr이 [4,3,2,1]인 경우는 [4,3,2]를 리턴 하고, [10]면 [-1]을 리턴 합니다.

제한 조건

arr은 길이 1 이상인 배열입니다.
인덱스 i, j에 대해 i ≠ j이면 arr[i] ≠ arr[j] 입니다.

처음 구현한 코드

function solution(arr) {
    const min = Math.min.apply(null, arr)
    return arr.length === 1 ? [-1] : arr.filter(num => num!==min)
}

처음엔 헤매다 sort 메서드 쓰면서 시간 초과로 탈락했었던 문제.. ㅋㅋ
sort 메서드는 원 배열의 정렬을 변형시키는 것이므로 원 배열을 따로 spread operator로 배열 자체를 복사하고 지지고볶고..를 해서 타임아웃이 된 것이다.

초반에 Math.min 메서드를 사용하지 않았던 이유는 단지 들어오는 인자가 배열이라는 이유였기 때문이다. Math.min 메서드는 배열을 받지 않는다 ! !
apply 메서드도 잘 모르는데 저렇게 하면 배열 원소를 비교해 min, max 값을 구할 수 있다길래 개념도 모르고 일단 사용했다.

다른 사람 풀이를 본 후 구현한 코드

function solution(arr) {
    const min = Math.min(...arr)
    return arr.length === 1 ? [-1] : arr.filter(num => num!==min)
}

한 동안 spread operator에 대해 빠삭하게 공부했다고 생각했는데, 배열 복사만 주구장창 하고 일반 값들을 복사할 수 있을 거라는 응용력이라고는 눈곱만큼도 없었다. 빠삭하지 않았던 것..

그래도 이번 기회에 Math.min, Math.max, apply 메서드에 대해 공부하게 되어 포스팅을 해보려고 한다.

Math.min(), Math.max()

Math.min(value1, value2, ..., valueN)
Math.max(value1, value2, ..., valueN)

이 함수들의 특징은 무엇일까 ?

  1. 매개변수로 받는 값은 배열이 아닌 단순히 입력된 숫자이다. 즉, 고유한 변수를 기대한다.
  2. 입력된 모든 값들은 숫자형으로 변환될 수 있는 타입이어야 한다.
    그렇지 않으면 NaN을 반환하며, 매개변수를 생략하면 -Infinity를 반환한다.
console.log(Math.max(1,3,4)); // 4
console.log(Math.max('1','3','4')); // 4 - 문자열도 가능
console.log(Math.max()); // -Infinity

const a = 1;
const b = 123;
console.log(Math.min(a,b)); // 1

const arr = [1, 100, 40, 20, 5]
console.log(Math.min(arr)) // NaN - 배열은 숫자형으로 변환 불가능하므로 NaN 반환
console.log(Math.min(...arr)) // 1

spread operator의 편의성에 박수..

apply()

function.apply(thisArg, [argsArray])

모든 매개변수는 option이지만, 그 중 주목할 점은 두 번째 매개변수가 유사 배열 객체라는 것이다.

원리는 다음과 같다.

  1. apply는 [argsArray] 배열의 원소 값들을 가져온다.
  2. 가져온 원소의 값들을 thisArg가 칭하는 function 함수의 인자로 받아 실행시킨다.

예시 코드와 함께 살펴보자.

const arr = [1, 100, 40, 20, 5]

console.log(Math.max.apply(null, arr))  // 100
console.log(Math.max.apply(Math, arr))  // 100

즉, null.max(1, 100, 40, 20, 5) 인 것이다.
null이 허용되는 이유는 Math가 내장객체이므로 this 값을 전달해주지 않아도 되기 때문이다.

그래도 이해가 안 간다면 다음 예시 코드를 보면 쉽게 이해할 수 있다.

let nameObj = { name: 'minngki' };
let test = function (city) { 
  return `Hello ${this.name}, Welcome to ${city}` 
};
console.log(test.apply(nameObj, ['Seoul'])); // 'Hello minngki, Welcome to Seoul'

test 함수의 인자로 전달받은, 즉 cityapply 함수로 인해 'seoul'이 되고,
test 함수를 호출하는데 제공될 this의 값은 nameObj이므로 this.name 값은 'minngki'가 되는 것이다.

알게 된 점

  1. this 개념 부족
    ES6 위주로 공부해서 그런지, this에 상당히 취약한 편이라 사실 apply 함수 메서드 때문에 포스팅을 한다 해도 과언이 아니다. this개념을 사용하는 메서드를 보고 괜히 긴장하지 말자..
  2. Math.min/max, apply 메서드의 원리
  3. spread operator 응용

참고

https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Math/max
https://basemenks.tistory.com/15

profile
애기코더 응애

0개의 댓글