티스토리 뷰

이 페이지는 자바스크립트에서 배열을 정렬할 때 사용하는 내장 함수 sort()에 대해서 설명하고 있다.

 

기본적으로 자바스크립트의 배열에는 정렬하여 반환하는 역할을 하는 sort() 메서드가 있다.

arr.sort([compareFunction])

 

기본 구조를 보면, compareFunction로 정의된 정렬 순서를 통해 arr라는 Array 객체를 정렬하여 반환한다.
compareFunction을 생략하면 기본적으로 각 요소의 유니코드 값에 따라 자동으로 정렬된다. (default 오름차순)

정렬되면서 기존의 배열 데이터가 변경되는 메서드이기 때문에 신중하게 사용해야한다.

const months = ['March', 'Jan', 'Feb', 'Dec'];
months.sort();
console.log(months);
// result: ['Dec', 'Feb', 'Jan', 'March']
const numbers = [1, 30, 4, 21, 100000];
numbers.sort();
console.log(numbers);
// result: [1, 100000, 21, 30, 4]

문자 정렬은 알파벳 순서대로 잘 정렬이 된 것을 확인할 수 있지만,

숫자는 ASCII 코드 순서로 정렬하기 떄문에 결과값이 우리가 생각했던 순서로 정렬되지 않음을 확인했다.

 

다음은 위의 오류를 개선하기 위한 코드이다.

1) 오름차순

numbers.sort(function(a, b) {
    return a - b;
});
console.log(numbers);
// result: [ 1, 4, 21, 30, 100000 ]

2) 내림차순

numbers.sort(function(a, b) {
    return b - a;
});
console.log(numbers);
// result: [ 100000, 30, 21, 4, 1 ]


해당 코드들은 화살표 함수를 사용하여 아주아주 짧고 간결하게 변환 가능하다. 

numbers.sort((a, b) => a - b); // 오름차순
numbers.sort((a, b) => b - a); // 내림차순


참고 - 화살표 함수 (arrow function expression) in ES6

 

화살표 함수

화살표 함수 표현(arrow function expression)은 function 표현에 비해 구문이 짧고  자신의 this, arguments, super 또는 new.target을 바인딩 하지 않습니다. 화살표 함수는 항상 익명입니다. 이  함수 표현은 메소드 함수가 아닌 곳에 가장 적합합니다. 그래서 생성자로서 사용할 수 없습니다.

developer.mozilla.org

 

 

Object 객체를 가진 리스트도 각각의 속성을 기준으로 정렬이 가능하다.

const items = [
  { name: 'Edward', value: 21 },
  { name: 'Sharpe', value: 37 },
  { name: 'And', value: 45 },
  { name: 'The', value: -12 },
  { name: 'Magnetic', value: 13 },
  { name: 'Zeros', value: 37 }
];

// value 기준으로 정렬
items.sort(function (a, b) {
  if (a.value > b.value) {
    return 1;
  }
  if (a.value < b.value) {
    return -1;
  }
  // a must be equal to b
  return 0;
});

// name 기준으로 정렬
items.sort(function(a, b) {
  const nameA = a.name.toUpperCase(); // ignore upper and lowercase
  const nameB = b.name.toUpperCase(); // ignore upper and lowercase
  if (nameA < nameB) {
    return -1;
  }
  if (nameA > nameB) {
    return 1;
  }

  // 이름이 같을 경우
  return 0;
});

이 코드 또한 화살표함수를 통해 변환이 가능하다.

// value 기준으로 정렬
items.sort((a, b) => a.value - b.value);
console.log(items);
/* result:
	[{ name: 'The', value: -12 },
	{ name: 'Magnetic', value: 13 },
	{ name: 'Edward', value: 21 },
	{ name: 'Sharpe', value: 37 },
	{ name: 'Zeros', value: 37 },
	{ name: 'And', value: 45 } ]
*/

// name 기준으로 정렬
items.sort((a, b) => (a.name > b.name) ? 1 : -1);
console.log(items);
/* result:
[ { name: 'And', value: 45 },
  { name: 'Edward', value: 21 },
  { name: 'Magnetic', value: 13 },
  { name: 'Sharpe', value: 37 },
  { name: 'The', value: -12 },
  { name: 'Zeros', value: 37 } ]
*/

 

문자열이 아닌 숫자를 비교하기 위한 compareFunction에서는 a에서 b를 뺄 수 있다. (Infinity 및 NaN이 포함되어 있지 않은 경우)

문자는 해당 로직이 성립하지 않기 때문에 부등호를 통해 비교하여 1 또는 -1을 리턴했다.

만약 a.name - b.name같은 형태로 작성한다면 어떻게될까?

items.sort((a, b) => {
    console.log(a.name - b.name);
    return a.name - b.name;
});

/* result:
NaN
NaN
NaN
NaN
NaN
[ { name: 'Edward', value: 21 },
  { name: 'Sharpe', value: 37 },
  { name: 'And', value: 45 },
  { name: 'The', value: -12 },
  { name: 'Magnetic', value: 13 },
  { name: 'Zeros', value: 37 } ]
*/

NaN NaN NaN!!!

에러로 인해 배열의 순서가 변경되지 않고 기존 데이터 그대로 출력된것을 확인할 수 있다.

댓글
최근에 올라온 글
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
Total
Today
Yesterday