배열 정렬하기 - Array.sort()

23556 단어 js배열js

arr.sort()

배열(arr)안의 요소들을 정렬시킨다.
문자열의 유니코드 포인트 순서대로 정렬되고, 원본배열을 건드리므로 유의해야 한다.

let nums = [1, -1, 4, 0, 2, 3, 10, 20, 12];
console.log(nums.sort());
// [-1, 0, 1, 10, 12, 2, 20, 3, 4]

let fruits = ['apple', Orange', 'orange', 'melon'];
console.log(fruits.sort());
// ['Orange', 'apple', 'melon', 'orange']

숫자는 문자열로 변환 후 유니코드 순으로 정렬되어서 원하는 순서대로 정렬되지 않았고 문자는 대문자가 앞으로 오도록 정렬된것을 볼 수 있다. 원하는 규칙에 따라서 정렬하기 위해서는 정렬 순서를 정의하는 매개변수가 필요하다.


compareFunction

매개변수를 사용해 오름차순이나 내림차순으로 정렬할 수 있다.
문자열대신 숫자를 비교해서 정렬하기 위해 파라미터로 함수를 정의한다.

1. 오름차순 정렬

arr.sort((a,b) => {
    return a - b;
});

비교함수에 a, b 두 개의 파라미터를 입력받아 a에서 b를 뺀 값이 양수인지, 음수인지를 이용해 정렬시킨다. 리턴값이 양수이면 앞/뒤 자리가 변하고, 리턴값이 음수이면 자리가 바뀌지 않는 원리.

let arr = [5, 3, 2, 1, 10];
arr.sort((a, b) => {
  if(a > b) return 1;
  if(a < b) return -1;
  if(a === b) return 0;
});
console.log(arr);

결과 [1, 2, 3, 5, 10]

요소의 순서대로 처음에 a에 5, b에 3이 할당된다.
5 - 3 = 2 이므로(a > b) 1을 리턴, 둘의 위치가 바뀌고 이때 배열은 [3, 5, 2, 1, 10]의 순서.
그 다음 5와 2를 비교 (5 - 2 = 3) = (a > b) 이므로 리턴값 양수 -> 위치 바뀜 -> [3, 2, 5, 1, 10]
이런식으로 요소의 위치가 고정될 때까지 반복해서 비교한다.

2. 내림차순 정렬

let arr = [5, 3, 2, 1, 10];
arr.sort((a,b) => {
  if(a > b) return -1;
  if(a < b) return 1;
  return 0;
});
console.log(arr);

// 위와 같은
// arr.sort((a, b) => {
//	return b - a;
// });

결과 [10, 5, 3, 2, 1]

3. 대소문자 구분없이 정렬

파라미터 a, b를 모두 대문자로 치환한 후 정렬시키는 방식을 이용한다.

let fruits = ['apple', 'Orange', 'orange', 'melon'];
fruits.sort((a, b) => {
	a = a.toUpperCase();
  	b = b.toUpperCase();
  
  	if(a > b) return 1;
  	if(b > a) return -1;
  	return 0;
});

결과 ['apple', 'melon', 'Orange', 'orange']

4. 객체 정렬

let list = [
    {name: 'banana', price: 3000},
    {name: 'apple', price: 1000},
    {name: 'orange', price: 500},
];

// name값을 기준으로 오름차순으로 정렬
let name_asc = list.sort((a,b) => {
    a = a.name.toUpperCase();
    b = b.name.toUpperCase();
    return a > b ? 1 : -1;
}) 

console.log(name_asc); 

결과

{ name: 'apple', price: 1000 },
{ name: 'banana', price: 3000 },
{ name: 'orange', price: 500 }

5. 콜백 함수 공용화

숫자 / 문자열에 공통으로 비교함수를 사용할 수 있도록 공용 함수를 만들어서 콜백함수로 사용한다.

function ASC(a, b) {
    if(typeof a === 'string') a = a.toUpperCase();
    if(typeof b === 'string') b = b.toUpperCase();

    return a > b ? 1 : -1;
};
function DESC(a, b) {
    if(typeof a === 'string') a = a.toUpperCase();
    if(typeof b === 'string') b = b.toUpperCase();

    return a < b ? 1 : -1;
};

let nums = [1, -1, 4, 0, 10, 20, 12];
let fruits = ['apple', 'Orange', 'orange', 'melon'];

console.log(nums.sort(ASC));
console.log(nums.sort(DESC));
console.log(fruits.sort(ASC));
console.log(fruits.sort(DESC));

결과

[-1, 0, 1, 4, 10, 12, 20]
[20, 12, 10, 4, 1, 0, -1]
['apple', 'melon', 'orange', 'Orange']
['Orange', 'orange', 'melon', 'apple']

6. localeCompare()

문자열의 순서를 비교함에 있어서 간단하게 localeCompare()메서드를 활용할수도 있다. localeCompare() 메서드는 기준 문자열과 비교했을 때 비교 대상 문자열이 정렬상 전에 오는지, 후에 오는지 혹은 같은 순서에 배치되는지를 알려주는 숫자를 리턴한다.

'a'.localeCompare('c') // -2 or -1 (음수의 결과값)
'check'.localeCompare('against'); // 2 or 1 (양수의 결과값)
'a'.localeCompare('a'); // 0

특히 한글 문자열에 사용하면 유용하다.

const str = [ '마', '가', '라', '나', '다' ];
const orderStr = str.sort((a,b) => a.localeCompare(b));
const 내림차순 = str.sort((a,b) => b.localeCompare(a));
// orderStr = [ '가', '나', '다', '라', '마' ]
// 내림차순 = [ '마', '라', '다', '나', '가' ]

좋은 웹페이지 즐겨찾기