The journey to becoming a developer

My future is created by what I do today, not tomorrow.

Algorithms/Programmers

[프로그래머스 Level 1] 문자열 내림차순으로 정렬하기 (자바스크립트)

Millie 2021. 10. 14. 20:15

Description

문자열 s에 나타나는 문자를 큰것부터 작은 순으로 정렬해 새로운 문자열을 리턴하는 함수, solution을 완성해주세요.
s는 영문 대소문자로만 구성되어 있으며, 대문자는 소문자보다 작은 것으로 간주합니다.

Constraints

str은 길이 1 이상인 문자열입니다.

 

My Solution

function solution(s) {
  return s.split('').sort().reverse().join('');
}

각종 메서드를 활용하여 간단하게 풀 수 있었다. 

 

Other's Solution

function solution(s) {
  return s
    .split('')
    .sort((a, b) => {
      if (a > b) return -1;
      if (b > a) return 1;
      return 0;
    })
    .join('');
}
function solution(s) {
  return s
    .split('')
    .sort((a, b) => (a < b ? 1 : -1))
    .join('');
}

 

이 문제는 간단하게 풀 순 있었지만, 다른 사람의 풀이를 0보고 sort 함수에 대해서 궁금증이 생겼다. 

위의 두 풀이 모두 reverse() 함수를 이용하지 않고, sort를 이용해 내림차순 정렬을 했다. 

sort((a, b) => b - a) 이런 식으로 내림차순 정렬을 할 수 있다는 건 알았는데, 저렇게 조건문을 사용하고 0, 1, -1을 리턴함으로써 정렬의 방식을 바꿀 수 있다는 것도 더 알아봐야겠다 생각했다. 

지금까지 sort 함수의 동작 원리를 잘 몰랐다는 생각에, MDN과 JavaScript Deep Dive 책을 함께 보면서 sort에 대해서 좀 더 이해하려고 했다. 그 내용을 정리해 보려고 한다. 

 

Array.prototype.sort()

sort는 배열 고차 함수에 속한다. 우선 고차 함수가 무엇인지부터 짚고 넘어가보자. 

Higher-Order Function, HOF

고차 함수란? 함수를 인수로 전달받거나 함수를 반환하는 함수

자바스크립트의 함수는 일급 객체이므로, 함수를 값처럼 인수로 전달할 수 있으며 반환할 수도 있다. 

고차 함수는 외부 상태의 변경이나 가변(mutable) 데이터를 피하고 불변성(immutability)를 지향하는 함수형 프로그래밍에 기반을 두고 있다. 

자바스크립트는 고차 함수를 다수 지원한다. 특히 배열은 매우 유용한 고차 함수를 제공하며, 활용도가 매우 높으므로 사용법을 잘 이해하는 것이 좋다.

 

함수형 프로그래밍

함수형 프로그래밍은 순수 함수와 보조 함수의 조합을 통해 로직 내에 존재하는 조건문과 반복문을 제거하여 복잡성을 해결하고, 변수의 사용을 억제하여 상태 변경을 피하려는 프로그래밍 패러다임이다. 

조건문이나 반복문은 로직의 흐름을 이해하기 어렵게 하여 가독성을 해치고, 변수는 누군가에 의해 언제든지 변경될 수 있어 오류 발생의 근본적 원인이 될 수 있기 때문이다.

함수형 프로그래밍은 결국 순수 함수를 통해 부수 효과를 최대한 억제하여 오류를 피하고 프로그램의 안정성을 높이려는 노력의 일환이라고 할 수 있다.


sort 메서드는 배열의 요소를 정렬한다. (기본적으로 오름차순)

원본 배열을 직접 변경하며, 정렬된 배열을 반환한다.

sort 메서드의 기본 정렬 순서는 유니코드 코드 포인트의 순서를 따른다. 

배열의 요소가 숫자 타입이라 할지라도 배열의 요소를 일시적으로 문자열로 변환한 후 유니코드 코드 포인트의 순서를 기준으로 정렬한다. 

숫자 요소를 정렬할 때는 sort 메서드에 정렬 순서를 정의하는 비교 함수를 인수로 전달해야 한다. 

비교 함수는 양수나 음수, 또는 0을 반환해야 한다.

  • 비교 함수의 반환값 < 0 : 비교 함수의 첫 번째 인수를 우선하여 정렬 
  • 비교 함수의 반환값 = 0 : 정렬하지 않음
  • 비교 함수의 반환값 > 0 : 두 번째 인수를 우선하여 정렬 

 

객체를 요소로 갖는 배열을 정렬하는 예제

const todos = [
  { id: 4, content: 'JavaScript' },
  { id: 1, content: 'HTML' },
  { id: 2, content: 'CSS' },
];

function compare(key) {
  return (a, b) => (a[key] > b[key] ? 1 : a[key] < b[key] ? -1 : 0);
}

위의 코드에서는 프로퍼티 값이 문자열인 경우엔 산술 연산으로 비교하면 NaN이 나오기 때문에 비교 연산을 사용하였다. 

 

Sort 메서드의 정렬 알고리즘

sort 메서드는 quicksort 알고리즘을 사용했었다.

quicksort 알고리즘은 동일한 값의 요소가 중복되어 있을 때 초기 순서와 변경될 수 있는 불안정한 정렬 알고리즘으로 알려져 있다. 

ECMAScript 2019(ES10)에서는 timsort 알고리즘을 사용하도록 바뀌었다.