알고리즘을 풀다가 아래와 같은 코드를 작성했고, 에러가 발생했다.
function solution(arr, intervals) {
return intervals.reduce((acc, cur) => {
return acc.push(...arr.slice(cur[0], cur[1]+1))
}, [])
}
TypeError: acc.push is not a function
at /solution.js:3:20
at Array.reduce (<anonymous>)
at Object.solution (/solution.js:2:22)
at /solution_test.js:30:22
at SolutionRunner.run (/solution_test.js:16:24)
at Object.<anonymous> (/solution_test.js:30:8)
at Module._compile (node:internal/modules/cjs/loader:1126:14)
at Object.Module._extensions..js (node:internal/modules/cjs/loader:1180:10)
at Module.load (node:internal/modules/cjs/loader:1004:32)
at Function.Module._load (node:internal/modules/cjs/loader:839:12)
오잉...?
push
메서드에서 에러가 난다고?
생각해 보니 push
에 바로 return을 해 본 적이 없었고, push
의 반환값이 요소를 추가하고 나서의 배열 값인줄 알았다.
MDN 문서를 찾아보니 push
에 대해 아래와 같이 설명하고 있었다.
push() 메서드는 배열의 끝에 하나 이상의 요소를 추가하고, 배열의 새로운 길이를 반환합니다.
const animals = ['pigs', 'goats', 'sheep'];
const count = animals.push('cows');
console.log(count);
// Expected output: 4
console.log(animals);
// Expected output: Array ["pigs", "goats", "sheep", "cows"]
JavaScript로 알고리즘을 푼지 오래되었음에도 이 사실을 이번에 처음 알게 되었다는 것에 충격이 커서 이렇게 블로그 글을 남기게 되었다.
그럼 내가 처음 작성한 코드의 문제점은 정확하게 무엇이었을까.
acc.push
가 push
메서드의 반환 값이 아닌, push
메서드 자체를 반환하기 때문에 발생한 에러다. push
메서드는 요소가 추가된 후의 배열의 길이를 반환하며, 이 반환 값이 reduce
함수의 다음 루프에 전달된다. 이것은 reduce
함수에 의해 예상되는 누적 값의 형태와 일치하지 않는다.
따라서 아래와 같이 코드를 수정했고, 알고리즘을 풀 수 있었다.
function solution(arr, intervals) {
return intervals.reduce((acc, cur) => {
acc.push(...arr.slice(cur[0], cur[1]+1))
return acc
}, [])
}
익숙하게 사용하던 메서드임에도 반환값을 정확하게 알고 있지 않았다. 메서드를 그냥 사용하기 보다 정의를 알고 정확하게 사용해야 한다는 것을 다시금 깨닫게 되었다.