如何按列值对二维数组进行排序?

问题描述 投票:0回答:16

谁能帮我在 JavaScript 中对二维数组进行排序?

它将包含以下格式的数据:

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

排序后应该如下所示:

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

基本上,按第一列排序。

干杯

javascript arrays sorting multidimensional-array
16个回答
153
投票

就这么简单:

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;
    }
}

83
投票

最好的方法是使用以下方法,因为第一列中可能有重复的值。

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]
});

66
投票

试试这个:

//WITH FIRST COLUMN
arr = arr.sort((a, b) => a[0] - b[0]);

//WITH SECOND COLUMN
arr = arr.sort((a, b) => a[1] - b[1]);

注意:原始答案使用大于(>)而不是减号(-),这是评论所指的错误。


16
投票

使用箭头功能,并按第二个字符串字段排序

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


12
投票

如果您像我一样,您不会希望每次想要更改排序依据的列时都更改每个索引。

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);

8
投票

一行:

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)
}

6
投票

如果您想根据第一列(包含 number 值)进行排序,请尝试以下操作:

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

如果您想根据第二列(其中包含 string 值)进行排序,请尝试以下操作:

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

附注对于第二种情况,您需要比较它们的 ASCII 值。


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"]]"

2
投票

我使用sort对数组进行排序

这是我的代码:

const sortArr = (arr) => {
    arr.sort((valA, valB) => valA[0] - valB[0])
    return arr
}

const arr = [
    [12, 'AAA'],
    [58, 'BBB'],
    [28, 'CCC'],
    [18, 'DDD']
]
console.log(sortArr(arr))


1
投票

站在 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 脚本。

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"],
                          ]"
*/

}

1
投票
Solution vary depend on column value is numeric or string. 

To sort by first column if value is numeric,
array.sort( (a, b) => a[0] - b[0]);

To sort by second column if value is numeric,
array.sort( (a, b) => a[1] - b[1]);

To sort by first column if value is string/letter,
array.sort( function(a, b) {
    const nameA = a[0].toUpperCase(); // to avoid case while sort
    const nameB = b[0].toUpperCase();
    if(nameA > nameB)
        return 1;
    else if(nameB > nameA)
        return -1;
    else
        return 0;     
})

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
投票

Sabbir Ahmed 好主意,但仅按第一个字符排序,三个:

array.sort((a, b) => (a[n].charCodeAt(0)*1000000 + a[n].charCodeAt(1)*1000 + a[n].charCodeAt(2)) - (b[n].charCodeAt(0)*1000000 + b[n].charCodeAt(1)*1000 + b[n].charCodeAt(2)));

0
投票

对指定排序顺序和列的二维数组进行排序。 默认顺序 0 表示没有变化,因此必须指定顺序:1 => 升序,-1 => 降序。默认列是 0。

let sort2d = (arr2d = [], order = 0, column = 0) => {
    if (column < 0 || column > 1) {
        if (order == 1) 
            return arr2d.sort((a, b) => a[column] - b[column])
        if (order == -1) 
            return arr2d.sort((a, b) => b[column] - a[column])
    }
    return arr2d
}

let arr2d = [ [5, 3], [2, 5], [9, 1], [4, 1] ]
console.log(sort2d(arr2d, 1, -1)) //  [ [ 2, 5 ], [ 5, 3 ], [ 9, 1 ], [ 4, 1 ] ]


0
投票

如果您想要一个对子数组具有固定长度的多维整数数组进行排序的解决方案 [ [ -6, 1, 5 ], [ -8, 3, 5 ], [ -8, 2, 6 ], [ -8, 3, 6 ] ]

const array = [ [ -6, 1, 5 ], [ -8, 3, 5 ], [ -8, 2, 6 ], [ -8, 3, 6 ] ]
const multiArraySort = (array, num) => {
  return array = array.sort((a,b) => {
    let boolean = true
    let i = 0 
    while(boolean){      
      if(a[i] === b[i]){        
        if(a[i+1] === b[i+1]){          
          i < num - 1 ? i++ : boolean = false
        }else {          
          return a[i+1] - b[i+1]          
        }        
      } else {                
        return a[i] - b[i]
      }
    }
    return 0
  })
}
// 3 represents the fixed length of sub-array
let sarray = multiArraySort(array, 3) //cant' assign in const array

答案:[ [ -8, 2, 6 ], [ -8, 3, 5 ], [ -8, 3, 6 ], [ -6, 1, 5 ] ]


0
投票

toSorted()方法允许我们对数组进行排序。返回一个包含有序元素的新数组,并且不修改原始数组。就像经典的 sort() 方法一样,我们可以向它传递一个比较函数来对元素进行排序。

const arr = [ [12, "AAA"], [58, "BBB"], [28, "CCC"], [18, "DDD"] ]; let arr1 = arr.toSorted(); let arr2 = arr.toSorted((a, b) => a[0] - b[0]); let arr3 = arr.toSorted((a, b) => a[1] - b[1]); console.log(arr1); console.log(arr2); console.log(arr3);

© www.soinside.com 2019 - 2024. All rights reserved.