정렬된 숫자 배열이 있지만 그중 일부 요소가 정렬 순서에서 벗어나 있는 경우를 생각해 보겠습니다. 이때 우리가 해야 할 일은, 이러한 배열을 입력받아 정렬 순서에서 어긋난 모든 요소만으로 구성된 하위 배열(subarray)을 반환하는 JavaScript 함수를 작성하는 것입니다.
문제 접근 방식
배열의 각 요소를 순회하면서 현재 요소가 이전 요소보다 연속적(또는 오름차순)으로 이어지지 않는지 확인하면 됩니다. 순서가 맞지 않는 요소만 별도의 배열에 모아 반환하는 방식으로 해결할 수 있습니다.
예제 코드
실제 구현 코드는 다음과 같습니다.
const arr = ["2", "3", "7", "4", "5", "6", "1"];
const findOutOfOrder = arr => {
let notInOrder = [];
notInOrder = arr.filter((el, ind) => {
return ind && this.next !== +el || (this.next = +el + 1, false);
}, {
next: null
});
return notInOrder;
};
console.log(findOutOfOrder(arr));
실행 결과
콘솔에 출력되는 결과는 다음과 같습니다.
[ '7', '1' ]
코드 동작 원리
이 코드의 핵심은 filter() 메서드의 두 번째 인자인 thisArg를 활용한 부분입니다.
- this 객체 초기화:
{ next: null }객체를 두 번째 인자로 전달하여 콜백 함수 내부의this가 상태를 기억할 수 있게 합니다. - 숫자 변환: 단항 더하기 연산자(
+el)를 사용해 문자열 요소를 숫자로 변환합니다. 원본 배열은 문자열 형태이므로 올바른 비교를 위해 반드시 필요한 과정입니다. - 조건 판별:
ind && this.next !== +el조건은 첫 번째 요소(ind === 0)는 건너뛰고, 이전 요소 다음 값(this.next)과 현재 요소가 일치하지 않으면 해당 요소를 결과 배열에 포함시킵니다. - next 값 갱신: 순서가 맞는 경우에는
this.next = +el + 1로 다음 기대값을 갱신하고false를 반환해 필터링합니다.
결과적으로 배열 ["2", "3", "7", "4", "5", "6", "1"]에서 '7'과 '1'만이 정렬 흐름에서 벗어난 요소이므로, 이 둘만 담긴 하위 배열이 반환됩니다.