Recent Posts
Recent Comments
Link
Today
Total
02-08 14:03
관리 메뉴

채린씨의 티스토리

[JavaScript] 32. 고차함수 본문

자료구조, 알고리즘/JavaScript 기초 문법

[JavaScript] 32. 고차함수

채린씨 2022. 3. 13. 17:39

* 고차함수

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

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

 

* sort()의 문제와 해결방법

- 문제점 1: 11이 101보다 뒤쪽에 정렬 (sort 메서드로 정렬될 때 배열의 요소가 일시적으로 문자열로 변경되기 때문에 발생하는 문제)

let nums = [1, 10, 20, 11, -1, 101, 0];
console.log(nums.sort());
// output: [ -1,  0,  1, 10, 101, 11, 20 ] (이게 뭔 정렬이여..)
더보기

문자열을 비교할 때는 가장 앞 글자부터 차례로 비교한다.

11과 101의 경우 각각 가장 앞 글자가 1, 1이므로다음 글자를 비교한다.

각각 두 번째 글자가 1, 0이므로 11이 101보다 뒤쪽에 정렬되는 것!

 

- 문제점 1의 해결방법: sort()의 매개변수로 함수를 넣어 해결

let nums = [1, 10, 20, 11, -1, 101, 0];

// 내부적으로 각 요소를 비교할 때, x - y가 양수이면 자리를 바꾸고, 그렇지 않으면 자리 유지
// ex. x = 11, y = 101
// => 11 - 101 = -90 (-90은 음수이므로 자리 유지)
let ascending_order = function (x, y) {
  return x - y;
};
console.log(nums.sort(ascending_order));
// output: [ -1, 0, 1, 10, 11, 20, 101 ] (오름차순 정렬 성공!)

// 내부적으로 각 요소를 비교할 때, y - x가 양수이면 자리를 바꾸고, 그렇지 않으면 자리 유지
// ex. x = 11, y = 101
// => 101 - 11 = 90 (90은 양수이므로 자리 바꿈)
let descending_order = function (x, y) {
  return y - x;
};
console.log(nums.sort(descending_order));
// output: [ 101, 20, 11, 10, 1, 0, -1 ] (내림차순 정렬 성공!)

 

- 문제점 2: 대소문자 구분되어 정렬 (sort 메서드로 정렬될 때 ASCII 코드 값 기준으로 정렬되기 때문에 발생하는 문제)

let fruits = ["Orange", "apple", "melon", "orange"];
console.log(fruits.sort());
// output: [ 'Orange', 'apple', 'melon', 'orange' ] (대소문자 구분 안하려면..?)
더보기

모든 정렬은 ASCII 코드 값 기준이다.

위 ASCII 코드 표를 보면 모든 대문자가 모든 소문자보다 ASCII 코드 값이 작은 것을 확인할 수 있다.

"Orange"와 "apple"의 경우 각각 가장 앞 글자가 O, a이므로 "apple"이 "Orange"보다 뒤쪽에 정렬되는 것!

 

- 문제점 2의 해결방법: sort()의 매개변수로 함수를 넣어 해결

let fruits = ["Orange", "apple", "melon", "orange"];

// 내부적으로 각 요소를 비교할 때, 모든 글자를 대문자로 변환한 것끼리 비교
// 반환되는 값이 양수이면 자리 바꿈, 음수이거나 0이면 자리 유지
// ex. x = Orange, y = apple
// => x = ORANGE, y = APPLE
// => ORANGE > APPLE 이므로 1 반환 (1은 양수이므로 자리 바꿈)
let ascending_order = function (x, y) {
  x = x.toUpperCase();
  y = y.toUpperCase();
  if (x > y) return 1;
  else if (x < y) return -1;
  else return 0;
};
console.log(fruits.sort(ascending_order));
// output: [ 'apple', 'melon', 'Orange', 'orange' ] (대소문자 구분 없이 사전순 정렬 성공!)

// 내부적으로 각 요소를 비교할 때, 모든 글자를 대문자로 변환한 것끼리 비교
// 반환되는 값이 양수이면 자리 바꿈, 음수이거나 0이면 자리 유지
// ex. x = Orange, y = apple
// => x = ORANGE, y = APPLE
// => ORANGE > APPLE 이므로 -1 반환 (-1은 음수이므로 자리 유지)
let descending_order = function (x, y) {
  x = x.toUpperCase();
  y = y.toUpperCase();
  if (x < y) return 1;
  else if (x > y) return -1;
  else return 0;
};
console.log(fruits.sort(descending_order));
// output: [ 'Orange', 'orange', 'melon', 'apple' ] (대소문자 구분 없이 사전역순 정렬 성공!)

 

- 문제점 1의 해결방법과 문제점 2의 해결방법 통일

let ascending_order = function (x, y) {
  // 비교대상이 문자열일 경우 모든 글자를 대문자로 변환한 것끼리 비교
  if (typeof x === "string") x = x.toUpperCase();
  if (typeof y === "string") y = y.toUpperCase();

  // x가 y보다 크면 1 반환 (양수이므로 자리바꿈), 그렇지 않으면 -1 반환 (음수이므로 자리 유지)
  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();

  // x가 y보다 작으면 1 반환 (양수이므로 자리바꿈), 그렇지 않으면 -1 반환 (음수이므로 자리 유지)
  return x < y ? 1 : -1;
};

let nums = [1, 10, 20, 11, -1, 101, 0];
console.log(nums.sort(ascending_order));
// output: [ -1,  0, 1, 10, 11, 20, 101 ] (숫자 오름차순 정렬 성공!)
console.log(nums.sort(descending_order));
// output: [ 101, 20, 11, 10, 1, 0, -1 ] (숫자 내림차순 정렬 성공!)

let fruits = ["Orange", "apple", "melon", "orange"];
console.log(fruits.sort(ascending_order));
// output: [ 'apple', 'melon', 'orange', 'Orange' ]
// (문자열 대소문자 구분 없이 사전순 정렬 성공!)
console.log(fruits.sort(descending_order));
// output: [ 'Orange', 'orange', 'melon', 'apple' ]
// (문자열 대소문자 구분 없이 사전역순 정렬 성공!)

 

 

 

'자료구조, 알고리즘 > JavaScript 기초 문법' 카테고리의 다른 글

[JavaScript] 34. 생성자  (0) 2022.03.13
[JavaScript] 33. 그 외 고차함수  (1) 2022.03.13
31. 배열 탐색 - 변형  (0) 2022.03.12
30. 배열 조작(!)  (0) 2022.03.12
29. Array  (0) 2022.03.09
Comments