我有一个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()方法?


当前回答

使用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"}
*/

其他回答

所以这里有一种排序算法,它可以在任何类型的对象数组中按任何顺序排序,而不受数据类型比较的限制(如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,则返回降序。

我还没有看到这种特别的方法,所以这里有一个我喜欢使用的简洁的比较方法,它适用于字符串和数字类型:

常量对象=[{first_nom:'Lazslo',last_nom:'Jamf'},{first_nom:'猪',last_nom:'Bodine'},{first_nom:'海盗',last_nom:'Prentice'}];常量排序依据=fn=>{常量cmp=(a,b)=>-(a<b)||+(a>b);return(a,b)=>cmp(fn(a),fn(b));};const getLastName=o=>o.last_nom;const sortByLastName=sortBy(getLastName);objs.sort(sortByLastName);console.log(objs.map(getLastName));

sortBy()的解释

sortBy()接受一个fn,该fn从一个对象中选择一个值用于比较,并返回一个可以传递给Array.prototype.sort()的函数。在本例中,我们正在比较o.last_nom。每当我们收到两个对象,例如

a = { first_nom: 'Lazslo', last_nom: 'Jamf' }
b = { first_nom: 'Pig', last_nom: 'Bodine' }

我们将它们与(a,b)=>cmp(fn(a),fn(b))进行比较。鉴于此

fn = o => o.last_nom

我们可以将比较函数扩展为(a,b)=>cmp(a.last_nom,b.last_nom)。由于逻辑OR(||)在JavaScript中的工作方式,cmp(a.last_nom、b.last_nom)相当于

if (a.last_nom < b.last_nom) return -1;
if (a.last_nom > b.last_nom) return 1;
return 0;

顺便说一下,这在其他语言中被称为三向比较“宇宙飞船”(<=>)运算符。

最后,这里是不使用箭头函数的ES5兼容语法:

var对象=[{first_nom:'Lazslo',last_nom:'Jamf'},{first_nom:'猪',last_nom:'Bodine'},{first_nom:'海盗',last_nom:'Prentice'}];函数sortBy(fn){函数cmp(a,b){return-(a<b)| |+(a>b);}返回函数(a,b){return cmp(fn(a),fn(b));};}函数getLastName(o){return o.last_nom;}var sortByLastName=sortBy(getLastName);objs.sort(sortByLastName);console.log(objs.map(getLastName));

试试看:

ES5之前

// Ascending sort
items.sort(function (a, b) {
   return a.value - b.value;
});


// Descending sort
items.sort(function (a, b) {
   return b.value - a.value;
});

ES6及以上

// Ascending sort
items.sort((a, b) => a.value - b.value);

// Descending sort
items.sort((a, b) => b.value - a.value);

这是一个简单的问题。我不知道为什么人们会有如此复杂的解决方案。

一个简单的排序函数(基于快速排序算法):

function sortObjectsArray(objectsArray, sortKey)
{
    // Quick Sort:
    var retVal;

    if (1 < objectsArray.length)
    {
        var pivotIndex = Math.floor((objectsArray.length - 1) / 2);  // Middle index
        var pivotItem = objectsArray[pivotIndex];                    // Value in the middle index
        var less = [], more = [];

        objectsArray.splice(pivotIndex, 1);                          // Remove the item in the pivot position
        objectsArray.forEach(function(value, index, array)
        {
            value[sortKey] <= pivotItem[sortKey] ?                   // Compare the 'sortKey' proiperty
                less.push(value) :
                more.push(value) ;
        });

        retVal = sortObjectsArray(less, sortKey).concat([pivotItem], sortObjectsArray(more, sortKey));
    }
    else
    {
        retVal = objectsArray;
    }

    return retVal;
}

使用示例:

var myArr =
        [
            { val: 'x', idx: 3 },
            { val: 'y', idx: 2 },
            { val: 'z', idx: 5 },
        ];

myArr = sortObjectsArray(myArr, 'idx');

尝试以下方式:

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

const compareBylastNom = (a, b) => {
    // Converting to uppercase to have case-insensitive comparison
    const name1 = a.last_nom.toUpperCase();
    const name2 = b.last_nom.toUpperCase();

    let comparison = 0;

    if (name1 > name2) {
        comparison = 1;
    } else if (name1 < name2) {
        comparison = -1;
    }
    return comparison;
}

console.log(objs.sort(compareBylastNom));