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


当前回答

试试看:

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

其他回答

let propName = 'last_nom';

let sorted_obj = objs.sort((a,b) => {
    if(a[propName] > b[propName]) {
        return 1;
    }
    if (a[propName] < b[propName]) {
        return -1;
    }
    return 0;
}

//This works because the js built-in sort function allows us to define our
//own way of sorting, this funny looking function is simply telling `sort` how to
//determine what is larger. 
//We can use `if(a[propName] > b[propName])` because string comparison is already built into JS
//if you try console.log('a' > 'z' ? 'a' : 'z')
//the output will be 'z' as 'a' is not greater than 'z'
//The return values 0,-1,1 are how we tell JS what to sort on. We're sorting on the last_nom property of the object. 
//When sorting a list it comes down to comparing two items and how to determine which one of them is "larger". 
//We need a way to tell JS how to determine which one is larger. 
//The sort defining function will use the case that returns a 1 to mean that a > b
//and the case that returns -1 to mean that a < b

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'旁边

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

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

这里有很多好的答案,但我想指出,它们可以非常简单地扩展,以实现更复杂的排序。您必须做的唯一一件事就是使用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可以在没有外部库或复杂代码的情况下走很长的路。它也非常有效,因为不需要进行字符串解析。

一个按属性对对象数组进行排序的简单函数:

function sortArray(array, property, direction) {
    direction = direction || 1;
    array.sort(function compare(a, b) {
        let comparison = 0;
        if (a[property] > b[property]) {
            comparison = 1 * direction;
        } else if (a[property] < b[property]) {
            comparison = -1 * direction;
        }
        return comparison;
    });
    return array; // Chainable
}

用法:

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

sortArray(objs, "last_nom"); // Asc
sortArray(objs, "last_nom", -1); // Desc