본문 바로가기
자료구조,알고리즘/Java Script 기초

JS기초 10 : 고차함수, sort()문제, 해결, 정렬

by 슈퍼 루키 2022. 7. 21.

고차함수

- 하나 이상의 함수를 매개변수로 취하거나 함수를 결과로 반환하는 함수

- 매개변수로 전달되는 함수는 콜백 함수(Callback function)

- 대표 배열 조작 메서드

- 임의 정렬 : Array.sort(callback function)

- 반복 작업 : Array.forEach()

- 콜백함수 결과 배열 반환 : Array.map()

- 조건 만족하는 하나의 값 반환 : Array.find()

- 조건 만족하는 값 배열로 반환 : Array.filter()

- 누적 결과 값 반환 : Array.reduce()

 

sort() 문제와 한계점

- 문제점 : 일의 자리 4가 10의 자리보다 뒤쪽에 정렬

- 원인 : sort 메서드로 정렬될 때 배열의 요소가 일시적으로 문자열로 변경되어 발생

- 예를 들어 10의 1은 4보다 작기 때문에

let nums = [1, -1, 4, 0, 10, 20, 12];

console.log(nums.sort()); // [-1,  0, 1, 10, 12, 20, 4]
console.log(nums.reverse()); // [4, 20, 12, 10, 1,  0, -1]

let ascending_order = function (x,y) {
  return x - y; // 값이 >0이면 자리 바뀌는 매커니즘
}
let descending_order = function (x,y) {
  return y - x;
}

console.log(nums.sort(ascending_order)); // [-1,  0,  1, 4, 10, 12, 20]
console.log(nums.sort(descending_order)); // [20, 12, 10, 4, 1,  0, -1]

- 한계점 : 대소문자 구분 없이 정렬하고 싶지만, 대소문자 구분되어 정렬

let fruits = ["apple", "Banana", "grapes", "banana"];

console.log(fruits.sort()); // [ 'Banana', 'apple', 'banana', 'grapes' ]

 

해결방법

let ascending_order = function (x,y){
  if(typeof x === "string") x= x.toUpperCase();
  if(typeof y === "string") y= y.toUpperCase();

  return x>y ? 1 : -1;
};

let descending_order = function (x,y){
  if(typeof x === "string") x= x.toUpperCase();
  if(typeof y === "string") y= y.toUpperCase();

  return x<y ? 1 : -1;
};

let fruits = ["apple", "banana", "grapes", "Banana"];
let nums = [1, -1, 4, 0, 10, 20, 12];

console.log(fruits.sort()); // [ 'Banana', 'apple', 'banana', 'grapes' ]

console.log(fruits.sort(ascending_order)); // [ 'apple', 'banana', 'Banana', 'grapes' ]
console.log(fruits.sort(descending_order));// [ 'grapes', 'Banana', 'banana', 'apple' ]

console.log(nums.sort(ascending_order)); // [-1,  0,  1, 4, 10, 12, 20]
console.log(nums.sort(descending_order)); // [20, 12, 10, 4, 1,  0, -1]

풀이

1. x>y이면 1(자리를 바꾼다) -> 작은 값이 앞으로 간다.

x<y이면 -1(자리를 바꾸지 않는다) -> 작은 값을 그대로 앞에 둔다.

let ascending_order = function (x,y){
  return x>y ? 1 : -1;
};

 

2. 값이 문자열이면 모두 대문자로 변환해 비교한다.

  if(typeof x === "string") x= x.toUpperCase();
  if(typeof y === "string") y= y.toUpperCase();

 

3. 문자열과 숫자열 모두 작은 값이 앞으로 가게 되어 뒤로 갈 수록 커지는 정렬이 완성된다.

console.log(fruits.sort(ascending_order);
console.log(nums.sort(ascending_order);

어제 코딩 테스트에서 모든 값을 대문자로 바꾼다던지 string.toUppercase()

비교를 통해 작은 값이 앞으로 오도록 정렬을 한다던지

let ascending_order = function (x,y){
  return x>y ? 1 : -1;
};

이부분 어떻게 구현할지 막막했는데 오늘 배웠다.

 

1이면 자리를 바꾸고 -1이면 자리를 안바꾸고 0이면 그대로 냅두는 것 같이 자동으로 설정되어 있는 매커니즘을 배우고 활용할 수 있도록 더 연습해야겠다.

반응형

댓글