JavaScript 진료 순서 정하기

zwundzwzig·2022년 12월 4일
0

algorithm

목록 보기
4/12
post-thumbnail

외과의사 머쓱이는 응급실에 온 환자의 응급도를 기준으로 진료 순서를 정하려고 합니다. 정수 배열 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;
}

그동안 내가 썼던 sort 메서드의 진실...

혹시나 해서 원본 배열과 정렬본 배열의 유무를 비교해보니..

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;
}

느낀 점

코딩테스트 문제를 접하면서 처음으로 자바스크립트 메모리 구조에 대한 문제의식을 느꼈다!

향후 얕은 복사, 깊은 복사 그리고 그에 해당하는 각각의 메소드를 심도있게 공부해야겠다고 느꼈다!

profile
개발이란?

1개의 댓글

comment-user-thumbnail
2022년 12월 4일

오 저도 오늘 이거풀었어요

답글 달기