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


当前回答

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

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

其他回答

您也可以使用自定义toString()方法(由默认比较函数调用)创建对象类型,而不是使用自定义比较函数:

function Person(firstName, lastName) {
    this.firtName = firstName;
    this.lastName = lastName;
}

Person.prototype.toString = function() {
    return this.lastName + ', ' + this.firstName;
}

var persons = [ new Person('Lazslo', 'Jamf'), ...]
persons.sort();

Deep

基于这篇优秀的教程,我想开发Vlad Bezden的答案,并解释为什么localeCompare优于标准比较方法,如strA>strB。让我们运行以下示例:

console.log(“Österreich”>“Zealand”);//我们期望错误console.log(“a”>“Z”);//我们期望错误

原因是在JavaScript中,所有字符串都使用UTF-16编码

让str=“”;//JavaScript中的字符顺序for(设i=65;i<=220;i++){str+=字符串.fromCodePoint(i);//代码到字符}console.log(str);

首先是大写字母(有小代码),然后是小写字母,然后是字符Ö(在z之后)。这就是为什么我们在第一个代码段中得到正确的原因,因为运算符>比较字符代码。

如您所见,比较不同语言中的字符是一项非常重要的任务,但幸运的是,现代浏览器支持国际化标准ECMA-402。所以在JavaScript中,我们有strA.localeCompare(strB)来完成任务(-1表示strA小于strB;1表示相反;0表示相等)

console.log('Österreich'.localeCompare('Zealand'));//我们期望-1console.log('a'.localeCompare('Z'));//我们期望-1

我想补充一点,localeCompare支持两个参数:语言和其他规则:

var对象=[{first_nom:'Lazslo',last_nom:'Jamf'},{first_nom:'猪',last_nom:'Bodine'},{first_nom:'海盗',last_nom:'Prentice'},{first_nom:'测试',last_nom:'jamf'}];objs.sort((a,b)=>a.last_nom.localeCompare(b.last_nom,'en',{sensitity:'case'}))console.log(objs);//在'>'比较中,'Jamf'不会在'Jamf'旁边

使用Lodash或Undercore.js,这是小菜一碟:

const sortedList = _.orderBy(objs, [last_nom], [asc]); // Ascending or descending

这里有很多好的答案,但我想指出,它们可以非常简单地扩展,以实现更复杂的排序。您必须做的唯一一件事就是使用OR运算符来链接比较函数,如下所示:

objs.sort((a,b)=> fn1(a,b) || fn2(a,b) || fn3(a,b) )

其中fn1,fn2。。。是返回[-1,0,1]的排序函数。这导致“按fn1排序”和“按fn2排序”,这在SQL中相当于ORDERBY。

此解决方案基于||运算符的行为,该运算符的求值结果为第一个可转换为true的求值表达式。

最简单的表单只有一个这样的内联函数:

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

使用last_nom和first_nom排序顺序有两个步骤,如下所示:

// ORDER_BY last_nom, first_nom
objs.sort((a,b)=> a.last_nom.localeCompare(b.last_nom) ||
                  a.first_nom.localeCompare(b.first_nom)  )

通用比较函数可以是这样的:

// ORDER BY <n>
let cmp = (a,b,n)=>a[n].localeCompare(b[n])

此函数可以扩展为支持数字字段、区分大小写、任意数据类型等。

您可以通过按排序优先级链接它们来使用它们:

// ORDER_BY last_nom, first_nom
objs.sort((a,b)=> cmp(a,b, "last_nom") || cmp(a,b, "first_nom") )
// ORDER_BY last_nom, first_nom DESC
objs.sort((a,b)=> cmp(a,b, "last_nom") || -cmp(a,b, "first_nom") )
// ORDER_BY last_nom DESC, first_nom DESC
objs.sort((a,b)=> -cmp(a,b, "last_nom") || -cmp(a,b, "first_nom") )

这里的重点是,采用函数方法的纯JavaScript可以在没有外部库或复杂代码的情况下走很长的路。它也非常有效,因为不需要进行字符串解析。

使用Ramda,

npm安装ramda

import R from 'ramda'
var objs = [ 
    { first_nom: 'Lazslo', last_nom: 'Jamf'     },
    { first_nom: 'Pig',    last_nom: 'Bodine'   },
    { first_nom: 'Pirate', last_nom: 'Prentice' }
];
var ascendingSortedObjs = R.sortBy(R.prop('last_nom'), objs)
var descendingSortedObjs = R.reverse(ascendingSortedObjs)