在Javascript中按名字(按字母顺序)对数组进行排序


644

我得到了一个数组(请参阅下面的数组中的一个对象),我需要使用JavaScript按名字排序。我该怎么做?

var user = {
   bio: null,
   email:  "user@domain.com",
   firstname: "Anna",
   id: 318,
   lastAvatar: null,
   lastMessage: null,
   lastname: "Nickson",
   nickname: "anny"
};

Answers:


1065

假设您有一个数组users。您可以使用users.sort并传递一个接受两个参数并进行比较的函数(比较器)

它应该返回

  • 如果第一个参数小于第二个参数,则为负数(应在结果数组的第二个参数之前放置)
  • 如果第一个参数较大,则为正数(应放在第二个参数之后)
  • 如果这两个元素相等,则为0。

在我们的情况下,如果两个元素是ab我们要比较a.firstnameb.firstname

例:

users.sort(function(a, b){
    if(a.firstname < b.firstname) { return -1; }
    if(a.firstname > b.firstname) { return 1; }
    return 0;
})

此代码将适用于任何类型。

请注意,在“现实生活”™中,当您比较字符串时,您通常希望忽略大小写,正确地对变音符号进行排序,诸如ß之类的怪异符号,因此您可能需要使用localeCompare。为清楚起见,请参见其他答案。


5
Friggin太棒了...我正在按ID对节点列表进行排序...就像一个护身符。一吨!
科迪2012年

74
对于那些以后再来的人,Mrchief的答案更好,因为它不区分大小写。
mlienau 2013年

25
@mlienau,我不会叫它更好或更糟。这只是另一个
RiaD

19
@RiaD足够公平。只是想不出很多情况下,按字母顺序对项目进行排序(包括大小写)非常有用,在这种情况下,“斑马”出现在列表中的“苹果”之前。
mlienau 2013年

15
此代码仅适用于英语国家/地区。在其他国家/地区,您应该使用ovunccetin的答案localeCompare
Spoike

539

使用ES6的代码最短!

users.sort((a, b) => a.firstname.localeCompare(b.firstname))

String.prototype.localeCompare()基本支持是通用的!


26
到目前为止,如果您现在生活在2017

51
如果您住在2018年,也将是最佳答案;)
Simone

48
可能也是2019年的最佳答案。
艾哈迈德·马勒基

22
也许是2020年 还是naaa?
kspearrin

13
啊,伙计,到2030年,大地将泛滥成灾,这只能在山区进行。
Starfs

343

像这样:

array.sort(function(a, b){
 var nameA=a.name.toLowerCase(), nameB=b.name.toLowerCase();
 if (nameA < nameB) //sort string ascending
  return -1;
 if (nameA > nameB)
  return 1;
 return 0; //default return value (no sorting)
});

43
在对字符串进行排序时,“ toLowerCase()”非常重要-大写字母可能会影响您的排序。
MarzSocks 2014年

3
如果其他人想知道toLowerCase会产生什么影响,则不会太大:'a'>'A' //true 'z'>'a' //true 'A'>'z' //false
SimplGy 2014年

14
@SimplGy我认为它的影响比您认为的要多。例如,如对已接受答案的注释中所述,了解您的排序功能是否会将字符串排序为'Zebra'高于字符串'apple'(如果不使用,则将这样做)是很重要的.toLowerCase()
PrinceTyke

1
@PrinceTyke是的,这是一个很好的案例。'Z' < 'a' // true'z' < 'a' // false
SimplGy 2015年

2
所有有效点,我想说排序总是一种“取决于”的事情。如果按名称排序,区分大小写可能无关紧要。在其他情况下可能会。无论如何,我认为一旦掌握了核心思想,就可以适应自己的具体情况。
Mrchief 2015年

336

如果比较的字符串包含Unicode字符,则可以使用如下所示的class localeCompare函数String

users.sort(function(a,b){
    return a.firstname.localeCompare(b.firstname);
})

3
String.localeCompare不支持Safari和IE <11 :)
CORSAIR 2014年

13
@CORSAIR它受支持,只是不支持的第二个和第三个参数。
Codler 2014年

6
所有主要IE浏览器都支持@CORSAIR示例中的用法:developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…。LocaleCompare还考虑了大写,因此我认为这种实现应被视为最佳实践。
马特·詹森

9
users.sort((a,b)=> a.firstname.localeCompare(b.firstname))//简短的n个可爱的ES6版本!
Nachiketha

4
坦克兄弟 在ES6中使用users.sort((a, b) => a.name.localeCompare(b.name))
Mohmmad Ebrahimi Aval'Oct 11'18

32

漂亮的小ES6一线:

users.sort((a, b) => a.firstname !== b.firstname ? a.firstname < b.firstname ? -1 : 1 : 0);

2
这是不完整的,因为它无法正确处理相等的值。
卡尔·约翰·约格伦

1
当然,感谢您发现,我添加了一个匹配值检查
Sam Logan

不错,我想如果您真的想要全部都放在一行上,则嵌套的三元数会变得易读,令人困惑
russter

24

我们可以使用localeCompare,但也需要检查键是否为假值

如果一个条目缺少lname,则下面的代码将不起作用。

obj.sort((a, b) => a.lname.localeCompare(b.lname))

所以我们需要像下面检查假值

let obj=[
{name:'john',lname:'doe',address:'Alaska'},
{name:'tom',lname:'hopes',address:'California'},
{name:'harry',address:'Texas'}
]
let field='lname';
console.log(obj.sort((a, b) => (a[field] || "").toString().localeCompare((b[field] || "").toString())));

要么

我们可以使用lodash,它非常简单。它将检测返回的值,即数字还是字符串,并进行相应的排序。

import sortBy from 'lodash/sortBy';
sortBy(obj,'name')

https://lodash.com/docs/4.17.5#sortBy


2
Lodash很整洁!以前没有听说过。很棒!
Derk Jan Speelman,

15

underscorejs提供了非常好的_.sortBy函数:

_.sortBy([{a:1},{a:3},{a:2}], "a")

或者您可以使用自定义排序功能:

_.sortBy([{a:"b"},{a:"c"},{a:"a"}], function(i) {return i.a.toLowerCase()})

2
第二个示例涉及返回字符串。是否sortBy检测到返回的值是字符串,从而执行字母排序?谢谢
superjos

12

如果我们正在对名称或带有特殊字符的内容(例如ñáéíóú(西班牙语中的常用字符))进行排序,则可以使用params 语言环境(在这种情况下为es表示西班牙语)和类似这样的选项

let user = [{'firstname': 'Az'},{'firstname': 'Áb'},{'firstname':'ay'},{'firstname': 'Ña'},{'firstname': 'Nz'},{'firstname': 'ny'}];


user.sort((a, b) => a.firstname.localeCompare(b.firstname, 'es', {sensitivity: 'base'}))


console.log(user)

可以在以下地址找到正式的语言环境选项:iana,es(西班牙语),de(德语),fr(法语)。关于灵敏度的 基础是:

只有基本字母不同的字符串才能比较为不相等。示例:a≠b,a =á,a =A。


8

基本上,您可以使用方法sort对数组进行排序,但是如果要对对象进行排序,则必须将函数传递给数组的排序方法,因此,我将为您提供使用数组的示例

user = [{
bio: "<null>",
email: "user@domain.com",
firstname: 'Anna',
id: 318,
"last_avatar": "<null>",
"last_message": "<null>",
lastname: 'Nickson',
nickname: 'anny'
},
{
bio: "<null>",
email: "user@domain.com",
firstname: 'Senad',
id: 318,
"last_avatar": "<null>",
"last_message": "<null>",
lastname: 'Nickson',
nickname: 'anny'
},
{
bio: "<null>",
email: "user@domain.com",
firstname: 'Muhamed',
id: 318,
"last_avatar": "<null>",
"last_message": "<null>",
lastname: 'Nickson',
nickname: 'anny'
}];

var ar = user.sort(function(a, b)
{
  var nA = a.firstname.toLowerCase();
  var nB = b.firstname.toLowerCase();

  if(nA < nB)
    return -1;
  else if(nA > nB)
    return 1;
 return 0;
});

为什么最后返回0?
大雄

=,当字符串相同时
SenadMeškin2015年

但是在那种情况下不应该将else其删除吗?否则,return 0将永远不会被读取
大雄(Nobita)2015年

2
不是“ else”,而是“ else if”
SenadMeškin15年


8

更简洁的表示法:

user.sort(function(a, b){
    return a.firstname === b.firstname ? 0 : a.firstname < b.firstname ? -1 : 1;
})

它更紧凑,但是违反了合同:(sign(f(a, b)) =-sign(f(b, a))对于a = b)
RiaD 2014年

3
返回a.firstname == b.firstname应该===用于完整性
puiu 2015年

6

同样对于asec和desc排序,您都可以使用此方法:假设我们有一个变量SortType,它指定了所需的升序或降序排序:

 users.sort(function(a,b){
            return   sortType==="asc"? a.firstName.localeCompare( b.firstName): -( a.firstName.localeCompare(  b.firstName));
        })

5

通用函数可以如下编写

    function getSortedData(data, prop, isAsc) {
        return data.sort((a, b) => (a[prop] < b[prop] ? -1 : 1) * (isAsc ? 1 : -1));
   }

您可以传递以下参数

  1. 您要排序的数据
  2. 数据中的属性应按其排序
  3. 最后一个参数是布尔类型。它检查您是否要按升序或降序排序

4

尝试

users.sort((a,b)=> (a.firstname>b.firstname)*2-1)


2
sort函数应返回-1,0,1。这个仅返回-1,1。
Radu Luncasu

@RaduLuncasu-您可以提供测试数据(用户数组)以表明上述解决方案给出了错误的结果吗?(据我所知,缺少零是没有问题的)
KamilKiełczewski19年

如果compareFunction(a,b)返回0,则a和b彼此保持不变,但对所有不同元素进行排序。
Radu Luncasu


@RaduLuncasu好的,但是该信息并不意味着必须为零。最好的显示方式是准备不起作用的数据-但据我所知这是不可能的-例如[9,8,7,6,5,1,2,3].sort((a,b) => a<b ? -1 : 1)
KamilKiełczewski19年

3

您可以将其用于对象

transform(array: any[], field: string): any[] {
return array.sort((a, b) => a[field].toLowerCase() !== b[field].toLowerCase() ? a[field].toLowerCase() < b[field].toLowerCase() ? -1 : 1 : 0);}

2

简单来说,您可以使用此方法

users.sort(function(a,b){return a.firstname < b.firstname ? -1 : 1});

1

您可以使用内置数组方法- sort。此方法以回调方法为参数



    // custom sort function to be passed as param/callback to the Array's sort method
    function myCustomSort(a, b) {
        return (a.toLowerCase() > b.toLowerCase()) ? 1 : -1;
    }

    // Actual method to be called by entity that needs sorting feature
    function sortStrings() {
        var op = Array.prototype.sort.call(arguments, myCustomSort);
    }

    // Testing the implementation
    var sortedArray = sortStrings("Burger", "Mayo1", "Pizza", "boxes", "Apples", "Mayo");
    console.log(sortedArray); //["Apples", "boxes", "Burger", "Mayo", "Mayo1", "Pizza"]


要理解此代码要注意的关键点。

  1. 在这种情况下,自定义方法myCustomSort应为每个元素对(来自输入数组)比较返回+1或-1。
  2. 在自定义排序回调方法中使用toLowerCase()/ toUpperCase(),以便区分大小写不会影响排序过程的正确性。

我希望这是足够清楚的解释。如果您认为需要发表评论,则需要更多信息。

干杯!


这不是正确的答案,因为它只执行小于和大于检查的结果,而不是相等的检查。
Steel Brain

与自2011年以来一直在讨论的任何答案相比,它也并没有带来什么新鲜事物。
amenthes '16

1

将最重要的答案放入原型中,以按键排序。

Array.prototype.alphaSortByKey= function (key) {
    this.sort(function (a, b) {
        if (a[key] < b[key])
            return -1;
        if (a[key] > b[key])
            return 1;
        return 0;
    });
    return this;
};

0

您可以使用类似的方法来消除区分大小写

users.sort(function(a, b){

  //compare two values
  if(a.firstname.toLowerCase() < b.firstname.toLowerCase()) return -1;
  if(a.firstname.toLowerCase() > b.firstname.toLowerCase()) return 1;
  return 0;

})

7
与Mrchief的回答相同。另一个缺点是toLowerCase每个比较执行四次,而不是两次。
amenthes '16

0

我的实现在旧版ES中效果很好:

sortObject = function(data) {
    var keys = Object.keys(data);
    var result = {};

    keys.sort();

    for(var i = 0; i < keys.length; i++) {
        var key = keys[i];

        result[key] = data[key];
    }

    return result;
};

0

仅作记录,如果您要具有命名的排序功能,语法如下:

let sortFunction = (a, b) => {
 if(a.firstname < b.firstname) { return -1; }
 if(a.firstname > b.firstname) { return 1; }
 return 0;
})
users.sort(sortFunction)

请注意,以下操作无效:

users.sort(sortFunction(a,b))
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.