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


当前回答

编写短代码:

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

其他回答

简单答案:

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

细节:

今天非常简单,您可以将字符串与localeCompare进行比较。正如Mozilla Doc所说:

localeCompare()方法返回一个数字,指示引用字符串在排序顺序上位于给定字符串之前、之后或与给定字符串相同。

    //example1:
    console.log("aaa".localeCompare("aab")); //-1
    console.log("aaa".localeCompare("aaa")); //0
    console.log("aab".localeCompare("aaa")); //1

    //example2:
    const a = 'réservé'; // with accents, lowercase
    const b = 'RESERVE'; // no accents, uppercase

    console.log(a.localeCompare(b));
    // expected output: 1
    console.log(a.localeCompare(b, 'en', { sensitivity: 'base' }));
    // expected output: 0

有关详细信息,请参阅Mozilla doclocaleCompare:

我将给您一个实现选择排序算法的解决方案。它简单有效。

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


function selection_Sort(num) {
  //console.log(num);
  var temp, index;
  for (var i = 0; i <= num.length - 1; i++) {
    index = i;

    for (var j = i + 1; j <= num.length - 1; j++) {
      // You can use first_nom/last_nom, any way you choose to sort

      if (num[j].last_nom < num[index].last_nom) {
        index = j;
      }
    }

    // Below is the swapping part
    temp = num[i].last_nom;
    num[i].last_nom = num[index].last_nom;
    num[index].last_nom = temp;
  };
  console.log(num);
  return num;
}

selection_Sort(objs);

您还可以创建一个动态排序函数,根据传递的值对对象进行排序:

function dynamicSort(property) {
    var sortOrder = 1;
    if(property[0] === "-") {
        sortOrder = -1;
        property = property.substr(1);
    }
    return function (a,b) {
        /* next line works with strings and numbers, 
         * and you may want to customize it to your needs
         */
        var result = (a[property] < b[property]) ? -1 : (a[property] > b[property]) ? 1 : 0;
        return result * sortOrder;
    }
}

所以你可以有一个这样的对象数组:

var People = [
    {Name: "Name", Surname: "Surname"},
    {Name:"AAA", Surname:"ZZZ"},
    {Name: "Name", Surname: "AAA"}
];

…当你这样做时,它会起作用:

People.sort(dynamicSort("Name"));
People.sort(dynamicSort("Surname"));
People.sort(dynamicSort("-Surname"));

事实上,这已经回答了问题。下面的部分是因为许多人联系我,抱怨它不适用于多个参数。

多个参数

您可以使用下面的函数生成具有多个排序参数的排序函数。

function dynamicSortMultiple() {
    /*
     * save the arguments object as it will be overwritten
     * note that arguments object is an array-like object
     * consisting of the names of the properties to sort by
     */
    var props = arguments;
    return function (obj1, obj2) {
        var i = 0, result = 0, numberOfProperties = props.length;
        /* try getting a different result from 0 (equal)
         * as long as we have extra properties to compare
         */
        while(result === 0 && i < numberOfProperties) {
            result = dynamicSort(props[i])(obj1, obj2);
            i++;
        }
        return result;
    }
}

这将使您能够执行以下操作:

People.sort(dynamicSortMultiple("Name", "-Surname"));

子类化数组

对于我们中能够使用ES6的幸运者,ES6允许扩展本机对象:

class MyArray extends Array {
    sortBy(...args) {
        return this.sort(dynamicSortMultiple(...args));
    }
}

这将实现:

MyArray.from(People).sortBy("Name", "-Surname");

方式1:

您可以使用Undercore.js。首先导入下划线。

 import * as _ from 'underscore';
 let SortedObjs = _.sortBy(objs, 'last_nom');

方法2:使用比较函数。

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

objs.sort(compare);

我会这样做:

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