열 값으로 2 차원 배열을 정렬하는 방법은 무엇입니까?


90

누구든지 JavaScript에서 2 차원 배열을 정렬하는 데 도움을 줄 수 있습니까?

다음 형식의 데이터가 있습니다.

[12, AAA]
[58, BBB]
[28, CCC]
[18, DDD]

정렬하면 다음과 같이 표시됩니다.

[12, AAA]
[18, DDD]
[28, CCC]
[58, BBB]

따라서 기본적으로 첫 번째 열을 기준으로 정렬합니다.

건배


3
당신이 알아야 할 다음의 모든 : MDN -에 Array.sort ()
jahroy

1
@PramodVemulapalli의 대답을 수락하십시오. 현재 높은 투표를받은 사람들은 모두 틀 렸습니다!
Bergi

@jahroy : 유형 강제가 아니라 일관된 비교 함수에 대한 요구 사항입니다.
BERGI

답변:


110

이것은 간단합니다.

var a = [[12, 'AAA'], [58, 'BBB'], [28, 'CCC'],[18, 'DDD']];

a.sort(sortFunction);

function sortFunction(a, b) {
    if (a[0] === b[0]) {
        return 0;
    }
    else {
        return (a[0] < b[0]) ? -1 : 1;
    }
}

문서읽어 보시길 바랍니다 .

두 번째 열을 기준으로 정렬하려면 다음을 수행하십시오.

a.sort(compareSecondColumn);

function compareSecondColumn(a, b) {
    if (a[1] === b[1]) {
        return 0;
    }
    else {
        return (a[1] < b[1]) ? -1 : 1;
    }
}

4
실제로 코드를 테스트하십시오. jsfiddle.net/DuR4B/2 . 게시 한 문서 링크에서 바로 확인할 수 있습니다. "compareFunction이 제공되지 않으면 요소를 문자열로 변환하고 문자열을 사전 식 (숫자가 아닌"사전 "또는"전화 번호부 ") 순서로 비교하여 정렬합니다. 예를 들어"80 "은 다음과 같습니다. 사전 순에서는 "9"앞에 있지만 숫자 정렬에서는 9가 80 앞에옵니다. "
Ian

3
@Ian-당신 말이 맞아요. 좋은 지적. 단순함에 대한 요점을 증명하기 위해 너무 흥분한 것 같습니다. 나는 그것을 테스트했지만 완전히는 아니었다. 이제 고칠 게요 ... 얼굴 전체에 계란을 묻히기 전에 샘플 데이터가 당신의 요점을 증명했으면 좋겠어요!
jahroy

하하 알아, 그런 일이 생기면 싫어. 너무 옳게 보이지만 예상대로 작동하지 않는 무언가가 내부적으로 변경되었습니다. 일종의으로 문자열을 비교할 같은 <>. 어쨌든, 나는 업데이트를 좋아한다 :)
Ian

1
@Ash-가장 좋은 곳은 문서입니다. 내가 JS에 대한 질문이있을 때 나는 모질라의 문서처럼, 그래서 난 항상 구글 기능 "MDN {{FUNCTION_NAME을}}. 검색어는 것이 경우" "MDN에 Array.sort" 당신을 제공합니다 여기 .
jahroy

1
... 문서에서 볼 수 있듯이 array.sort () 메서드는 JavaScript에서 매우 일반적인 함수를 인수로 사용합니다. 에 Array.sort () 메소드가 그것을 전달하는 기능과 함께 무엇을 알고있는 방식으로 설계되어 그것의 요소를 비교하는 데 사용합니다. 여기에 함수를 참조로 전달하는 방법을 보여주기 위해 만든 정말 절름발이 바이올린이 있습니다. 죄송합니다.
jahroy

65

첫 번째 열에 반복적 인 값이있을 수 있으므로 가장 좋은 방법은 다음을 사용하는 것입니다.

var arr = [[12, 'AAA'], [12, 'BBB'], [12, 'CCC'],[28, 'DDD'], [18, 'CCC'],[12, 'DDD'],[18, 'CCC'],[28, 'DDD'],[28, 'DDD'],[58, 'BBB'],[68, 'BBB'],[78, 'BBB']];

arr.sort(function(a,b) {
    return a[0]-b[0]
});

이것은 정답이며 숫자의 두 자리를 모두 고려합니다. 감사!
nick

52

이 시도

//WITH FIRST COLUMN
arr = arr.sort(function(a,b) {
    return a[0] - b[0];
});


//WITH SECOND COLUMN
arr = arr.sort(function(a,b) {
    return a[1] - b[1];
});

참고 : 원래 답변은 마이너스 (-) 대신보다 큼 (>)을 사용하여 주석이 잘못된 것으로 언급했습니다.


8
노골적으로 잘못된 솔루션에 대한 8 개의 찬성 투표? 나는 이것을 믿을 수 없다. 비교 함수 에 대해 읽고 음수 값을 반환해야하는시기를 이해하십시오.
Bergi

6
Bergi가 말했듯이 이것은 올바른 해결책이 아닙니다. 많은 경우에 작동 할 수 있지만 예상대로 작동하지 않고 머리를 긁적 거리는 경우가 있습니다 (나에게 발생했습니다). 문제의 핵심은이 솔루션의 비교 함수가 두 가지 상태 (true / 1, false / 0) 만 반환하지만 세 가지 상태 (0, 0보다 크고, 0보다 작음)를 반환해야한다는 것입니다.
thdoan

1
나를 위해 일하지 않았습니다. @jahroy는 정답을 가진 사람이다
erdomester

주석을 읽는 사람들을위한 참고 사항 : 답변은 1 월 5 일에 수정되었습니다. 지금은 맞습니다 (비교 기능은 세 가지 가능한 상태를 반환합니다).
marlar

@Bergi, 이것을 지적 해 주셔서 감사합니다. (저에게는 IE11에서 제대로 작동하지 않습니다) 귀하의 의견을 볼 때까지 (크롬에서 작동하는 이유) 이해할 수 없었습니다. 감사!
Alex Nevsky

12

화살표 기능을 사용하고 두 번째 문자열 필드를 기준으로 정렬

var a = [[12, 'CCC'], [58, 'AAA'], [57, 'DDD'], [28, 'CCC'],[18, 'BBB']];
a.sort((a, b) => a[1].localeCompare(b[1]));
console.log(a)


10

나와 같은 사람이라면 정렬 기준이되는 열을 변경할 때마다 각 인덱스를 변경하고 싶지 않을 것입니다.

function sortByColumn(a, colIndex){

    a.sort(sortFunction);

    function sortFunction(a, b) {
        if (a[colIndex] === b[colIndex]) {
            return 0;
        }
        else {
            return (a[colIndex] < b[colIndex]) ? -1 : 1;
        }
    }

    return a;
}

var sorted_a = sortByColumn(a, 2);

나는 당신의 대답을 보았습니다. 똑같은 추론으로 직접 답을 작성한 후-작은 차이를 제외하고-실제로 직접 정렬하는 함수를 반환합니다.
olamotte 2017-04-05

3

특별한 것은 없습니다. 배열에서 특정 인덱스의 값을 반환하는 데 드는 비용을 절약 할 수 있습니다.

function sortByCol(arr, colIndex){
    arr.sort(sortFunction)
    function sortFunction(a, b) {
        a = a[colIndex]
        b = b[colIndex]
        return (a === b) ? 0 : (a < b) ? -1 : 1
    }
}
// Usage
var a = [[12, 'AAA'], [58, 'BBB'], [28, 'CCC'],[18, 'DDD']]
sortByCol(a, 0)
console.log(JSON.stringify(a))
// "[[12,"AAA"],[18,"DDD"],[28,"CCC"],[58,"BBB"]]"

이 대답이 여기 나와 어떻게 다른 가요?
Charles Clayton

1
1. 당신은 a[colIndex]몇 번이고 사용 하고 있지만 나는 여기에서 그것을 잡습니다 a = a[colIndex]. 더 효율적입니다. 2. 나는 다른 맛을 사용하여 if더 짧게 만듭니다. 3. 함수 arr의 결과 로 반환되지 않습니다. sortByCol즉, 함수를 다른 참조를 만드는 데 사용할 수 없습니다. 도움이 되었기를 바랍니다.
Vikas Gautam

3

한 줄로 :

var cars = [
  {type:"Volvo", year:2016},
  {type:"Saab", year:2001},
  {type:"BMW", year:2010}
]


function myFunction() {
  return cars.sort((a, b)=> a.year - b.year)
}

3

첫 번째 열 ( 숫자 값 포함)을 기준으로 정렬하려면 다음을 시도하십시오.

arr.sort(function(a,b){
  return a[0]-b[0]
})

두 번째 열 ( 문자열 값 포함)을 기준으로 정렬하려면 다음을 시도하십시오.

arr.sort(function(a,b){
  return a[1].charCodeAt(0)-b[1].charCodeAt(0)
})

두 번째 경우 PS, ASCII 값을 비교해야합니다.

도움이 되었기를 바랍니다.


0

내 사용 사례에는 수십 개의 열이 포함되어 있으므로 @jahroy의 답변을 약간 확장했습니다. (또한 @ charles-clayton이 동일한 아이디어를 가지고 있다는 사실을 깨달았습니다.)
정렬 기준으로 사용하려는 매개 변수를 전달하고 정렬 기능이 비교가 발생하도록 원하는 인덱스로 재정의됩니다.

var ID_COLUMN=0
var URL_COLUMN=1

findings.sort(compareByColumnIndex(URL_COLUMN))

function compareByColumnIndex(index) {
  return function(a,b){
    if (a[index] === b[index]) {
        return 0;
    }
    else {
        return (a[index] < b[index]) ? -1 : 1;
    }
  }
}

0

charles-clayton 및 @ vikas-gautam의 어깨에 서서 OP에서와 같이 열에 문자열이있는 경우 필요한 문자열 테스트를 추가했습니다.

return isNaN(a-b) ? (a === b) ? 0 : (a < b) ? -1 : 1 : a-b  ;

이 테스트 isNaN(a-b)는 문자열을 숫자로 강제 변환 할 수 없는지 확인합니다. 가능한 경우 a-b테스트가 유효합니다.

엄격한 동등성 테스트 (a === b)는 항상 false를 반환 하므로 혼합 유형의 열을 정렬하면 항상 재미있는 결과를 얻을 수 있습니다 . 여기에서 MDN보기

Logger 테스트가 포함 된 전체 스크립트입니다. Google Apps Script를 사용합니다.

function testSort(){

function sortByCol(arr, colIndex){
    arr.sort(sortFunction);
    function sortFunction(a, b) {
        a = a[colIndex];
        b = b[colIndex];
       return isNaN(a-b) ? (a === b) ? 0 : (a < b) ? -1 : 1 : a-b  ;  // test if text string - ie cannot be coerced to numbers.
       // Note that sorting a column of mixed types will always give an entertaining result as the strict equality test will always return false
       // see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Equality_comparisons_and_sameness

       }
}
// Usage
var a = [ [12,'12', 'AAA'],
          [12,'11', 'AAB'],
          [58,'120', 'CCC'],
          [28,'08', 'BBB'],
          [18,'80', 'DDD'],
        ]
    var arr1 = a.map(function (i){return i;}).sort();  // use map to ensure tests are not corrupted by a sort in-place.

    Logger.log("Original unsorted:\n     " + JSON.stringify(a));
    Logger.log("Vanilla sort:\n     " + JSON.stringify(arr1));
    sortByCol(a, 0);
    Logger.log("By col 0:\n     " + JSON.stringify(a));
    sortByCol(a, 1);
    Logger.log("By col 1:\n     " + JSON.stringify(a));
    sortByCol(a, 2);
    Logger.log("By col 2:\n     " + JSON.stringify(a));

/* vanilla sort returns " [
                            [12,"11","AAB"],
                            [12,"12","AAA"],
                            [18,"80","DDD"],
                            [28,"08","BBB"],
                            [58,"120","CCC"]
                          ]
   if col 0 then returns "[
                            [12,'12',"AAA"],
                            [12,'11', 'AAB'],
                            [18,'80',"DDD"],
                            [28,'08',"BBB"],
                            [58,'120',"CCC"]
                          ]"
   if col 1 then returns "[
                            [28,'08',"BBB"],
                            [12,'11', 'AAB'],
                            [12,'12',"AAA"],
                            [18,'80',"DDD"],
                            [58,'120',"CCC"],

                          ]"
   if col 2 then returns "[
                            [12,'12',"AAA"],
                            [12,'11', 'AAB'],
                            [28,'08',"BBB"],
                            [58,'120',"CCC"],
                            [18,'80',"DDD"],
                          ]"
*/

}

가능한 관심사 업데이트-2019 년 7 월 2 일. 정렬이 이제 '안정적'입니다. 여기에서 읽으십시오. (Mathias BynensVerified @mathias를 통해) v8.dev/features/stable-sort
DeeKay789
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.