배열 정렬과 조작
sort 로 차례를 바꾸고 잘라 내고 이어 붙입니다. 얕은 복사를 주의합니다.
차례를 바꾸고 잘라 냅니다
이 단원의 것들은 두 갈래로 나뉩니다. 원래 배열을 바꾸는 것과 새 배열을 돌려주는 것입니다. 이 구분을 놓치면 원본이 조용히 바뀌어 찾기 어려운 버그가 됩니다.
- 바꾸는 것 —
sort·reverse·push·pop - 새로 돌려주는 것 —
slice·concat·join·map·filter
sort — 숫자를 조심해야 합니다
const names = ["다래", "가람", "나은"]; names.sort(); console.log(names); const numbers = [10, 9, 100, 1]; numbers.sort(); console.log(numbers);
글자는 제대로 정렬되는데 숫자는 어긋납니다. sort 는
값을 글자로 바꿔 비교하기 때문입니다. 글자로는
"100" 이 "9" 보다
앞섭니다.
비교 방법을 넘겨주기
함수를 넘기면 그 함수로 비교합니다. 두 값을 받아
음수를 돌려주면 앞, 양수를 돌려주면 뒤로 갑니다. 그래서 오름차순은
a - b 입니다.
const numbers = [10, 9, 100, 1]; numbers.sort((a, b) => a - b); console.log(numbers); numbers.sort((a, b) => b - a); console.log(numbers);
sort 는 원본을 바꿉니다
const original = [3, 1, 2]; const sorted = original.sort((a, b) => a - b); console.log(original); console.log(sorted === original);
돌려받은 것이 같은 배열입니다. 원본을 두고 정렬한 것만 얻으려면 먼저 복사해야 합니다 — 아래에서 다룹니다.
slice · concat · join
이 셋은 원본을 그대로 두고 새것을 돌려줍니다.
const items = ["가", "나", "다", "라"]; console.log(items.slice(1, 3)); console.log(items.concat(["마"])); console.log(items.join(" · ")); console.log(items);
slice(1, 3) 은 1번째부터 3번째 앞까지입니다.
1.5 의 문자열 자르기와 같은 규칙입니다.
join 은 배열이 아니라 글자를 돌려줍니다.
원본을 지키며 정렬하기
slice() 를 인자 없이 부르면 전체가 복사됩니다.
복사본을 정렬하면 원본은 그대로입니다.
const scores = [85, 42, 91]; const sorted = scores.slice().sort((a, b) => b - a); console.log(sorted); console.log(scores);
이 복사는 한 겹만 복사합니다. 배열 안에 배열이나 객체가 들어 있으면 그것은 여전히 같은 것을 가리킵니다. 이것을 얕은 복사 라고 하며 3.7 에서 다시 다룹니다.
처음에 자주 걸리는 것
글자로 비교되어 [1, 10, 100, 9] 가 됩니다.
숫자에는 언제나 (a, b) => a - b 를 넘기세요.
화면에 정렬해 보여 주려고 한 번 불렀는데 원래 데이터의 차례까지 바뀝니다.
원본이 필요하면 slice() 로 복사한 뒤 정렬하세요.
이름이 한 글자 다른데 하는 일이 다릅니다.
slice 는 잘라 복사하고,
splice 는 원본에서 덜어냅니다.
직접 해보기
점수 배열에서 큰 순서로 앞 세 개만 뽑아 출력하세요. 원본은 그대로 두어야 합니다.
이름 배열을 가나다순으로 정렬해
가람, 나은, 다래 형태의 한 줄로 만들어
출력하세요.
이 단원의 정리
sort는 값을 글자로 바꿔 비교합니다. 숫자에는(a, b) => a - b를 넘깁니다.sort와reverse는 원본을 바꿉니다.slice·concat·join은 원본을 두고 새것을 돌려줍니다.slice()로 복사한 뒤 정렬하면 원본이 지켜집니다.- 그 복사는 한 겹만 복사합니다(얕은 복사).