我有一个JavaScript对象数组:

var objs = [ 
    { first_nom: 'Lazslo', last_nom: 'Jamf'     },
    { first_nom: 'Pig',    last_nom: 'Bodine'   },
    { first_nom: 'Pirate', last_nom: 'Prentice' }
];

如何在JavaScript中按last_nom的值对它们进行排序?

我知道排序(a,b),但这似乎只适用于字符串和数字。是否需要向对象添加toString()方法?


当前回答

所以这里有一种排序算法,它可以在任何类型的对象数组中按任何顺序排序,而不受数据类型比较的限制(如Number、String等):

function smoothSort(items,prop,reverse) {
    var length = items.length;
    for (var i = (length - 1); i >= 0; i--) {
        //Number of passes
        for (var j = (length - i); j > 0; j--) {
            //Compare the adjacent positions
            if(reverse){
              if (items[j][prop] > items[j - 1][prop]) {
                //Swap the numbers
                var tmp = items[j];
                items[j] = items[j - 1];
                items[j - 1] = tmp;
            }
            }

            if(!reverse){
              if (items[j][prop] < items[j - 1][prop]) {
                  //Swap the numbers
                  var tmp = items[j];
                  items[j] = items[j - 1];
                  items[j - 1] = tmp;
              }
            }
        }
    }

    return items;
}

第一参数项是对象数组,prop是要排序的对象的键,reverse是一个布尔参数,如果为true,则返回升序,如果为false,则返回降序。

其他回答

这里有一个函数,您可以使用它按多个对象对列表进行排序,如果第一个对象相等,则第二个顺序将用作回退。如果可能的话,空值也应忽略到回退顺序。

function sortObjects(list, orderBy){
    list.sort(function(a, b){
        let byIndex = 0;
        let order = orderBy[byIndex];
        while(!a[order.by] || !b[order.by] || a[order.by] === b[order.by]){
            byIndex++;
            if(byIndex >= orderBy.length){break;}
            order = orderBy[byIndex];
        }
        if(!a[order.by] || !b[order.by] || a[order.by] === b[order.by]){
            return false;
        }
        if(order.desc){
            return a[order.by] < b[order.by];
        }
        return a[order.by] > b[order.by];
    });
    return list;
}

用法:

var objs = [
    {a: 10, b: 20, c: 30},
    {a: 30, b: 10, c: 20},
    {a: 20, b: 10, c: 30},
];

sortObjectList(objs, [{by: 'a'}]);
[
    {a: 10, b: 20, c: 30},
    {a: 20, b: 10, c: 30},
    {a: 30, b: 10, c: 20},
]

sortObjectList(objs, [{by: 'a', desc: true}]);
[
    {a: 30, b: 10, c: 20},
    {a: 20, b: 10, c: 30},
    {a: 10, b: 20, c: 30},
]

sortObjectList(objs, [{by: 'b', desc: true}, {by: 'c'}]);
[
    {a: 10, b: 20, c: 30},
    {a: 30, b: 10, c: 20},
    {a: 20, b: 10, c: 30},
]

另一个例子:

var objs = [
    {a: 5, b: 5},
    {a: 10, b: 15},
    {a: 15, b: 25},
    {b: 10},
    {b: 20},
    {a: 10, b: 30},
    {a: 10, b: 12},
];

sortObjectList(objs, [{by: 'a'}, {by: 'b'}]);
[
    {a: 5, b: 5},
    {b: 10},
    {a: 10, b: 12},
    {a: 10, b: 15},
    {b: 20},
    {a: 10, b: 30},
    {a: 15, b: 25},
]

编写自己的比较函数非常简单:

function compare( a, b ) {
  if ( a.last_nom < b.last_nom ){
    return -1;
  }
  if ( a.last_nom > b.last_nom ){
    return 1;
  }
  return 0;
}

objs.sort( compare );

或内联(由Marco Demaio转交):

objs.sort((a,b) => (a.last_nom > b.last_nom) ? 1 : ((b.last_nom > a.last_nom) ? -1 : 0))

或简化为数字(由Andre Figueiredo转交):

objs.sort((a,b) => a.last_nom - b.last_nom); // b - a for reverse sort

使用JavaScript排序方法

排序方法可以修改为使用比较函数对数字、字符串甚至对象数组进行排序。

比较函数作为可选参数传递给排序方法。

此比较函数接受两个参数,通常称为a和b。根据这两个参数可以修改排序方法,使其按需工作。

如果compare函数返回的值小于0,那么sort()方法将a排序到比b低的索引。如果compare函数返回的值等于0,那么sort()方法将保持元素位置不变。如果compare函数返回的值大于0,那么sort()方法会以大于b的索引对a进行排序。

使用上述概念应用于对象,其中a将是对象属性。

var对象=[{first_nom:'Lazslo',last_nom:'Jamf'},{first_nom:'猪',last_nom:'Bodine'},{first_nom:'海盗',last_nom:'Prentice'}];函数比较(a,b){如果(a.last_nom>b.last_nom)返回1;如果(a.last_nom<b.last_nom)返回-1;返回0;}objs.sort(比较);console.log(对象)//要获得更好的外观,请使用console.table(objs)

我会这样做:

[...objs].sort((a, b) => a.last_nom.localeCompare(b.last_nom))

使用xPrototype的sortBy:

var o = [
  { Name: 'Lazslo', LastName: 'Jamf'     },
  { Name: 'Pig',    LastName: 'Bodine'   },
  { Name: 'Pirate', LastName: 'Prentice' },
  { Name: 'Pag',    LastName: 'Bodine'   }
];


// Original
o.each(function (a, b) { console.log(a, b); });
/*
 0 Object {Name: "Lazslo", LastName: "Jamf"}
 1 Object {Name: "Pig", LastName: "Bodine"}
 2 Object {Name: "Pirate", LastName: "Prentice"}
 3 Object {Name: "Pag", LastName: "Bodine"}
*/


// Sort By LastName ASC, Name ASC
o.sortBy('LastName', 'Name').each(function(a, b) { console.log(a, b); });
/*
 0 Object {Name: "Pag", LastName: "Bodine"}
 1 Object {Name: "Pig", LastName: "Bodine"}
 2 Object {Name: "Lazslo", LastName: "Jamf"}
 3 Object {Name: "Pirate", LastName: "Prentice"}
*/


// Sort by LastName ASC and Name ASC
o.sortBy('LastName'.asc, 'Name'.asc).each(function(a, b) { console.log(a, b); });
/*
 0 Object {Name: "Pag", LastName: "Bodine"}
 1 Object {Name: "Pig", LastName: "Bodine"}
 2 Object {Name: "Lazslo", LastName: "Jamf"}
 3 Object {Name: "Pirate", LastName: "Prentice"}
*/


// Sort by LastName DESC and Name DESC
o.sortBy('LastName'.desc, 'Name'.desc).each(function(a, b) { console.log(a, b); });
/*
 0 Object {Name: "Pirate", LastName: "Prentice"}
 1 Object {Name: "Lazslo", LastName: "Jamf"}
 2 Object {Name: "Pig", LastName: "Bodine"}
 3 Object {Name: "Pag", LastName: "Bodine"}
*/


// Sort by LastName DESC and Name ASC
o.sortBy('LastName'.desc, 'Name'.asc).each(function(a, b) { console.log(a, b); });
/*
 0 Object {Name: "Pirate", LastName: "Prentice"}
 1 Object {Name: "Lazslo", LastName: "Jamf"}
 2 Object {Name: "Pag", LastName: "Bodine"}
 3 Object {Name: "Pig", LastName: "Bodine"}
*/