열 값으로 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.