ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 데이터 정렬하기
    개발/Javascript & jQuery 2018. 2. 7. 13:58

    배열 내 데이터를 정렬할 일이 생겼을 때, 편하게 sort 함수나 reverse 함수를 써서 정렬할 수도 있고

    괜히 정렬 알고리즘을 짜서 정렬할 수도 있다.

    오늘은 한가하니까 두 방법을 모두 써서 배열 내 데이터를 정렬했다.




    1. Array.prototype.sort(), Array.prototype.reverse() 를 사용하여 정렬


    오늘은 작정하고 공부를 하는 날이니까 여유롭게 기술문서를 보러갔다.

    https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Array/sort


    sort() 함수에 대한 기술을 먼저 보러 갔더니 눈에 띄는 구절이 있다.



    sort () 메서드는 배열의 요소를 적절한 위치에 정렬하고 배열을 반환합니다. 

    기본 정렬 순서는 문자열 유니 코드 코드 포인트에 따릅니다.



    뭔가 함정이 있는 것 같다.

    아래 예제로 나온 코드를 보니 대충 감이 오는 것도 같다.



    var fruit = ['cherries', 'apples', 'bananas'];

    fruit.sort(); // ['apples', 'bananas', 'cherries']


    var scores = [1, 10, 21, 2]; 

    scores.sort(); // [1, 10, 2, 21]

    // 10이 2,

    // Unicode 코드 포인트 순서에서 '10'이 '2'앞에 오기 때문에.


    var things = ['word', 'Word', '1 Word', '2 Words'];

    things.sort(); // ['1 Word', '2 Words', 'Word', 'word']

    // 유니 코드에서 숫자는 대문자 앞에옵니다.

    // 소문자 앞에옵니다.



    fruit 배열은 알파벳 순서대로 정렬이 되었는데

    scores 배열은 숫자 크기대로 정렬이 되지 않았다. 

    좀 더 찾아보니 숫자의 경우 암시적으로 문자열로 형변환 하기 때문에 그렇다고 한다. 

    즉, 배열이름.sort() 를 실행하면 유니코드 값의 순서에 따라 정렬해주는 것이다. 

    따라서 숫자로 된 배열을 수의 크기대로 정렬하려면 배열이름.sort(정렬용 메소드명) 과 같이 선언해준다.

    이 정렬용 메소드는 배열 요소 간의 우선순위를 정하는데 쓰인다. 


    기술문서에서는 이 정렬용 메소드명을 compare 로 정했다.

    공식적으로 기술해준 Description을 좀 더 살펴봤다.


    - compare(a, b) < 0 : a가 앞으로

    - compare(a, b) = 0 : a와 b의 순서를 바꾸지 않음

    - compare(a, b) > 0 : b가 앞으로


    이걸 자바스크립트 함수로 표현하면 짠



    function compare ( a, b ) {

          if (a is less than b by some ordering criterion) {  // if ( a < b ) 면 -1 반환

                return -1;

          }

          if (a is greater than b by the ordering criterion) {  // if ( a > b ) 면 1 반환

                return 1;

          }

          // a must be equal to b

          return 0;

    }



    이걸 내가 기억하기 쉽게 후려쳐서 압축하자면

    "정렬용 메소드가 양수를 반환하는 조건을 만족시킬 때 배열 요소를 정렬한다." 


    위의 compare 메소드는 a 가 b보다 클 때 1을 반환한다. 

    즉 앞에 서있던 애가 뒤에 서있는 애보다 크면 1을 반환 → 더 작은 애가 앞으로 오도록 오름차순 정렬을 하게 만든다. 


    이 로직을 뒤집어서 if ( a < b) return 1; 이라고 선언해주면 

    앞에 서있던 애가 뒤에 서있는 애보다 작을 때 1을 반환 → 더 큰 애가 앞으로 오도록 내림차순 정렬을 하게 만든다.

     

    근데 자바스크립트 sort()를 써서 숫자를 정렬하는 방법을 검색하다보면 대부분 아래와 같이 기술한다.



    function ascending ( a, b ) {

    return a - b;

    // 혹은 array.sort((a, b) => a - b);



    function descending ( a, b ) {

    return b - a;

    }

    // 혹은 array.sort((a,b) => b - a);


     

    이건 대체 무슨 로직으로 돌아가는 걸까??? 싶었는데 생활코딩의 sort() 토픽 밑에 어떤 분께서 달아주신 댓글에서 개념을 잡았다.

    "sort() 함수의 파라미터값으로 들어가는 정렬용 메소드는 배열 요소 간 우선순위를 판단한다."

    라는 정의에 주목하면 좀 더 이해가 쉽다.


    모든 배열 요소들끼리 a - b 를 실행한 후 그 결과값을 sort() 에 넣으면 

    a - b 연산의 결과값이 작은 것부터 큰 순서대로 정렬하는 것이다. 



    sort() 와 함께 묶어서 공부하긴 했지만 reverse()는 sort()와 살짝 개념이 다르다.

    https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Array/reverse


    reverse() 메소드의 설명부터 보면



    reverse 메서드는 대상 배열을 반전시키고 원본 배열을 변형시킵니다. 그리고 배열의 참조를 반환합니다.




    var myArray = ['one', 'two', 'three'];

    myArray.reverse(); 

     

    console.log(myArray); // ['three', 'two', 'one']



    reverse() 메소드만 단독으로 써서는 완벽하게 오름차순 또는 내림차순 정렬은 불가능하다.

    쓴다면 미리 sort() 메소드를 써서 정렬한 후 reverse() 를 통해 순서를 뒤집어주는 정도가 된다.





    2. 선택정렬 알고리즘을 만들어 정렬하기


    이중 for 문과 조건문을 합치면 간단하게 선택정렬 알고리즘을 만들 수 있다.

    임시변수를 하나 선언하여 조건 만족 시 배열 내 요소 간 순서를 옮겨주는게 핵심



    정렬 알고리즘별 비교까지 시작하면 더 길어질 것 같으니 이건 다음 기회에....

    댓글

Designed by Tistory.