오늘의 코드워

매개변수로 숫자 엘리먼트로 이루어진 어레이를 주어지고 그 어레이에서 가장 작은 수를 골라 제거한 다음 나머지 엘리먼트들을 순서 그대로 리턴하게 하는 알고리즘을 작성하는 문제다. 처음에는 sort로 정렬한 다음 첫번째 엘리먼트만 제거하면 되겠지 하는 얕은 생각으로 빨리 작성했다가 코드워 자체 테스트에서 fail한 다음 왜 그럴까 생각 해 보고 문제를 다시 읽어보니 엘리먼트의 순서가 바뀌면 안 되었다. 그래서 고민을 하다가 결국 스택오버플로우에서 생각 해보니 Math.min 메서드 였다. 그걸로 가장 작은 엘리먼트 값을 찾고 그걸 어레이에서 제거하는 방식으로 해 보자 해서 일단 코드를 작성했다.

1
2
3
4
5
6
7
8
function removeMinimum(numbers) {
let data = Math.min(...numbers); // 스프레드 오퍼레이터는 참 편하다..ㅎㅎ
let index = numbers.indexOf(data);
if(index > -1) {
numbers.splice(index, 1);
}
return numbers;
}

이 방식으로 하면 일단 샘플 테스트는 통과가 된다. 하지만 답안 제출을 하면서 한가지 테스트를 더 하게 되는데 바로 요즘 react공부하면서 가장 많이 듣게 되는 방식이다. Don’t mutate the data!! 원래의 매개변수를 변경하면 안된다는 것인데, 이 test가 최종 테스트에 있었다. 그러다 보니 논리적으론 맞는데.. 최종 테스트에서 계속 실패하게 되었다.
결국 다시 문제를 읽고 매개변수를 변경하면 안된다는 지시문을 발견하고 아래 코드 처럼 다시 변경했다.

1
2
3
4
5
6
7
8
9
function removeSmallest(numbers) {
let arr = Array.from(numbers);
let data = Math.min(...arr);
let index = numbers.indexOf(data);
if(index > -1) {
arr.splice(index, 1);
}
return arr;
}

주어진 numbers 매개변수를 Array.from()메소드를 이용해서 복제하고 그 복제한 어레이만 이용해서 문제를 풀었다. 최종 테스트에서는 역시 통과!!!

능력자분들의 코드

1
2
3
4
function removeSmallest(numbers) {
const min = Math.min(...numbers);
return numbers.filter((num, idx, arr) => idx !== arr.indexOf(min));
}

filter메소드를 이용해서 푼 방식인데 내 수준에서는 가장 깔끔하고 이해하기도 편했다.

1
2
3
4
function removeSmallest(numbers) {
let indexOfMin = numbers.indexOf(Math.min(...numbers));
return [...numbers.slice(0, indexOfMin), ...numbers.slice(indexOfMin + 1)];
}

가장 많은 칭찬을 받은 코드다. slice와 스프레드오퍼레이터로 concat메소드를 재현했다.

정리

음.. 역시 ES6가 도입되고 나니 알고리즘 문제 해결 방식 자체도 엄청 나게 편해 진다는 걸 느끼고 있다. 그건 사실 다른 문제 해결 부분에서는 그렇게 좋지 않겠지만 일단 접근방식만 안 다는 걸로도 일단 계단을 오르고 있다는 거니까 지금 나 정도의 수준에서는 일단 만족하고 더 높은 단계에서는 진짜 기본적인 문법만으로 해결이 가능하게 해야 하겠다.