프론트엔드/JAVASCRIPT

[javascript] callback함수로 오름차순/내림차순 정렬

진기명기 2023. 2. 23. 16:52

 

* sort()의 문제점 해결 'callback함수' 이용!

🫠 지난 포스팅에서 sort()의 문제점으로 10이 9보다 작다고 인식된다는 점을 확인했다. 아래 링크를 통해 문제점을 한 번 더 확인해 보자. 이번 포스팅에서는 이러한 sort()의 문제점을 해결하는 방법을 정리하고자 한다. sort()를 제대로 사용해보자!

 

👉🏻 sort()의 문제점 확인 ⬇️⬇️⬇️

https://cyjcyj.tistory.com/44

 

[javascript] 배열(Array) 변형 sort()와 reverse()

* 배열(Array) 변형 메서드인 sort()와 reverse() 🫠 callback 함수를 이용하지 않고, 배열을 변형할 수 있는 정말 간단한 방법이 있는데, 이는 바로 sort(), reverse(), 또 하나로는 join()이 있다. join()은 저번

cyjcyj.tistory.com

 

 

 


🫠 callback 함수로 이용하여 오름차순 정렬하기

/* sort() 정렬 문제점 */

let nums = [10, 25, 9, 4, 52, 7];

// console.log(nums.sort()); // [ 10, 25, 4, 52, 7, 9 ]


/* sort() 정렬 */

let asc = (x,y) => {
  return x - y
}

result = nums.sort(asc)
console.log(result) // [ 4, 7, 9, 10, 25, 52 ]
👉🏻 output : 주석 처리 확인
asc 함수를 살펴보자. x-y의 값이 실제 0보다 큰 값으로 반환이 될 때, 매개변수로 받은 두 개의 인자 위치가 변경된다.
👇🏻
1) 10과 25 비교 (10 - 25 = -15) 음수이므로 위치 변경 x
2) 10과 9 비교 (10 - 9 = 1) 양수이므로 둘의 위치 변경 O
3) 9와 4 비교 (9 - 4 = 5) 양수이므로 둘의 위치 변경 O
.
.
따라서 모두 비교하여 작은 수일수록 앞쪽에 정렬되어 오름차순 정렬이 된 것을 확인할 수 있다. 
두 수를 비교하여 양수가 나올 경우, 둘의 위치를 변경해주는 asc 함수를 sort함수의 callback함수로 사용하면 된다. 

 

 

 

🫠 내림차순으로 정렬하고 싶을 때는?

/* sort() 정렬 문제점 극복 */

let nums = [10, 25, 9, 4, 52, 7];

// console.log(nums.sort()); // [ 10, 25, 4, 52, 7, 9 ]

let dsc = (x,y) => {
  return y - x
}

result = nums.sort(dsc)
console.log(result) // [ 52, 25, 10, 9, 7, 4 ]
👉🏻 output : 주석 처리 확인
dsc 함수를 살펴보자. y-x의 값이 실제 0보다 큰 값으로 반환이 될 때, 매개변수로 받은 두 개의 인자 위치가 변경된다.
👇🏻
1) 10과 25 비교 (25- 10 = 15) 양수이므로 위치 변경 O
2) 25과 9 비교 (9 - 25 = -16) 음수이므로 둘의 위치 변경 X
3) 25와 4 비교 (4 - 25 = -21) 음수이므로 둘의 위치 변경 X
.
.
따라서 모두 비교하여 큰 수일수록 앞쪽에 정렬되어 내름차순 정렬이 된 것을 확인할 수 있다. 
두 수를 비교하여 양수가 나올 경우, 둘의 위치를 변경해주는 dsc 함수를 sort함수의 callback함수로 사용하면 된다. 

 

 

 

 


🫠 대/소문자 구분 없이 오름차순 하고 싶은 경우

let colors = ['red', 'Red', 'pink', 'blue', 'Blue', 'Green'];

let asc2 = (x,y) => {
  x = x.toLowerCase()
  y = y.toLowerCase()

  if(x > y) {return 1} 
  else if(y > x) {return -1} 
  else {return 0}
}

let result = colors.sort(asc2)
console.log(result) // [ 'blue', 'Blue', 'Green', 'pink', 'red', 'Red' ]
👉🏻 output : 주석 처리 확인
asc2 함수를 살펴보자.
👇🏻
1) 우선 대/소문자 구분을 없애기 위해 toLowerCase() 또는 toUpperCase()를 사용하여 소문자 or 대문자 중 하나로 변형해주자. (여기서는 toLowerCase()를 사용하여 colors의 모든 요소를 소문자로 변경)
2) 만약 x가 y보다 클 경우, return 1을 해줘서 x와 y의 위치를 변경해 주자 
3) 만약 y가 x보다 클 경우에는 return -1을 해줘서 위치 변경을 해주지 말고,
4) 2번과 3번에 해당되지 않는다면 0을 넣어 그냥 무시해라
.
.
대/소문자 구분 없이 blue와 Blue가 b로 가장 작은 값이므로 앞쪽에 정렬되었고, red와 Red의 r이 가장 큰 값으로 뒤쪽에 정렬된 것을 확인할 수 있다. (blue와 Blue의 정렬은 순서 상관없이 정렬된 것)

 

 

 

🫠 대/소문자 구분 없이 내림차순으로 정렬하고 싶을 때는?

let colors = ['red', 'Red', 'pink', 'blue', 'Blue', 'Green'];

let dsc2 = (x,y) => {
  x = x.toUpperCase()
  y = y.toUpperCase()

  if(y > x) {return 1} 
  else if(x > y) {return -1} 
  else {return 0}
}

let result = colors.sort(dsc2)
console.log(result) // [ 'red', 'Red', 'pink', 'Green', 'blue', 'Blue' ]
👉🏻 output : 주석 처리 확인
dsc2 함수를 살펴보자.
👇🏻
1) 우선 대/소문자 구분을 없애기 위해 toLowerCase() 또는 toUpperCase()를 사용하여 소문자 or 대문자 중 하나로 변형해주자. (이번에는 toUpperCase()를 사용하여 colors의 모든 요소를 대문자로 변경)
2) ~ 4)의 경우에는 (x > y) 일 때 1의 값을 반환해주는 것이 아닌 (y > x) 일 때 1을 반환해 주고, (x > y) 일 때 -1을 return 해 준다.

내림차순 역시 대/소문자 순서 상관없이 정렬된 것을 확인할 수 있다.  

 

 

 

🫠 동시에 사용해보자! (숫자 & 대/소문자)

let colors = ['red', 'Red', 'pink', 'blue', 'Blue', 'Green'];
let nums = [10, 25, 9, 4, 52, 7];

let num_col_mix_asc = (x,y) => { // 오름차순 정렬
  if(typeof x === 'string') x = x.toLowerCase()
  if(typeof y === 'string') y = y.toLowerCase()

  return x > y ? 1 : -1
}

let num_col_mix_dsc = (x,y) => { // 내림차순 정렬
  if(typeof x === 'string') x = x.toLowerCase()
  if(typeof y === 'string') y = y.toLowerCase()

  return y > x ? 1 : -1
}

console.log(nums.sort(num_col_mix_asc)) // [ 4, 7, 9, 10, 25, 52 ]
console.log(colors.sort(num_col_mix_asc)) // [ 'Blue', 'blue', 'Green', 'pink', 'Red', 'red' ]
console.log(nums.sort(num_col_mix_dsc)) // [ 52, 25, 10, 9, 7, 4 ]
console.log(colors.sort(num_col_mix_dsc)) // [ 'red', 'Red', 'pink', 'Green', 'blue', 'Blue' ]
💡 nums를 오름/내림차순으로 정렬하고 싶을 때, (x - y) or (y - x)를 하지 않고, (return x > y ? 1 : -1) or ( return y > x ? 1 : -1)로 나타내어도 된다.