외과의사 머쓱이는 응급실에 온 환자의 응급도를 기준으로 진료 순서를 정하려고 합니다. 정수 배열
emergency
가 매개변수로 주어질 때 응급도가 높은 순서대로 진료 순서를 정한 배열을 return하도록 solution 함수를 완성해주세요.
사실, 프로그래머스 3,4000등을 달리고 있는 필자는 이 문제를 보자마자 어렵지 않게 풀 수 있을 거 같았다.
인자로 받는 문자열 배열을 크기에 맞게 정렬한 뒤 해당 정렬본 배열 인덱스들에 원본 인덱스 값들을 매핑시켜 값을 구하면 될 거 같았다.
하지만, 왠지 모르게 자꾸 리턴 값이 정렬본 배열 인덱스값들이 아닌, [1,2,3...n]
처럼 순서대로 찍히고 있었다.
function solution(emergency) {
var indexArray = [];
var sortArray = emergency.sort((a, b) => b - a);
emergency.map(x => indexArray.push(sortArray.indexOf(x)+1))
return indexArray;
}
혹시나 해서 원본 배열과 정렬본 배열의 유무를 비교해보니..
function solution(emergency) {
var indexArray = [];
var sortArray = emergency.sort((a, b) => b - a);
emergency.map(x => {indexArray.push(sortArray.indexOf(x)+1)})
return sortArray === emergency; // true
}
두 배열은, 심지어 엄격 비교 ===
에서도 같게 나왔다!! 즉, 내가 배열을 정렬한 로직은 원본 배열도 훼손시키고 있던 것이다!
그리고 부랴부랴 검색해 들어간 mdn에서 해당 궁금증이 해소됐다.
Array.prototype.sort()
return 값 : 정렬한 배열. 원 배열이 정렬되는 것에 유의하세요. 복사본이 만들어지는 것이 아닙니다.
MDN web docs
따라서 sort 메소드를 배열에 사용하면, 새로운 배열이 생기는 게 아니라 원본 배열의 참조 주소를 변형시키는 것이다!!!
해결 방안으로, 자주 가는 코어 자바스크립트 사이트에서 마침 비슷한 문제에 대한 답을 주었다.
바로 Array.prototype.slice()
를 활용하는 것!
slice 메소드는 원본 배열에 관여하지 않는, 얕은 복사를 실행하는 메소드이고 인자에 값을 넣지 않으면 원본 배열과 똑같은 배열을 반환한다.
function solution(emergency) {
var sortArray = emergency.slice().sort((a, b) => b - a);
var indexArray = [];
emergency.map(x => indexArray.push(sortArray.indexOf(x)+1));
return indexArray;
}
코딩테스트 문제를 접하면서 처음으로 자바스크립트 메모리 구조에 대한 문제의식을 느꼈다!
향후 얕은 복사, 깊은 복사 그리고 그에 해당하는 각각의 메소드를 심도있게 공부해야겠다고 느꼈다!
오 저도 오늘 이거풀었어요