【问题标题】:How can I sort a javascript array of objects numerically and then alphabetically? [duplicate]如何按数字然后按字母顺序对 javascript 对象数组进行排序? [复制]
【发布时间】:2012-10-05 16:31:44
【问题描述】:

可能重复:
Sorting objects in an array by a field value in JavaScript

如何按数字(按 id)然后按字母(按名称)对对象数组进行排序?

当前的方式是提供无效的输出。

这是我要排序的对象

var items = [
    {
        "id": 165,
        "name": "a"
    },
    {
        "id": 236,
        "name": "c"
    },
    {
        "id": 376,
        "name": "b"
    },
    {
        "id": 253,
        "name": "f"
    },
    {
        "id": 235,
        "name": "e"
    },
    {
        "id": 24,
        "name": "d"
    },
    {
        "id": 26,
        "name": "d"
    }
]

以及我尝试排序的方式

items.sort(function(a, b) {
    return (a.id - b.id);
}).sort(function(a, b) {
    return (a.name - b.name);
});

这里是 jsfiddle。

http://jsfiddle.net/jh4xb/

编辑:很抱歉造成混乱,我被这个问题困扰了一段时间。

我想要完成的是首先按最高 id 排序,然后按字母顺序排序,所以最后它应该看起来像:

var items = [
    {
        "id": 376,
        "name": "b"
    },
    {
        "id": 253,
        "name": "f"
    },
    {
        "id": 236,
        "name": "c"
    },
    {
        "id": 235,
        "name": "e"
    },
    {
        "id": 165,
        "name": "a"
    },
    {
        "id": 26,
        "name": "d"
    },
    {
        "id": 24,
        "name": "d"
    }
]

【问题讨论】:

  • 您可能需要一个更好的示例来说明您要完成的工作,因为在此示例中,首先按id 排序没有意义,因为所有ids 和names是独一无二的。相当于只按name排序。
  • 同意 - 您希望此处的排序语义到底是什么?
  • 不确定您希望通过对列表进行两次排序来实现什么。当您执行return (a.name - b.name) 时,您正试图从另一个字符串中减去一个字符串。不会发生(你可能想要localeCompare。)

标签: javascript jquery arrays sorting


【解决方案1】:

我认为最好只...

items.sort(function(a, b) { 
  return a.id - b.id  ||  a.name.localeCompare(b.name);
});

第二种基本上会否定第一种,所以你必须做一次。 )

a.id - b.id || a.name.localeCompare(b.name) 表达式将首先比较ids;仅当它们相等时,它才会比较名称(并返回此比较的结果)。

如果您需要颠倒顺序,请交换位置(b.id - a.id 等) - 或者直接否定整个事情:

items.sort(function(a, b) { 
  return - ( a.id - b.id  ||  a.name.localeCompare(b.name) );
});

这是JSFiddle(必须稍微简化数据以表明我的观点)。

【讨论】:

  • 正是我需要的!对不起,我不是很清楚,但这是完美的!谢谢!
【解决方案2】:

创建一个通用函数以按您的意愿对其进行排序。检查下面的dynamicSort函数

var items = [
{
 "id": 165,
 "name": "a"},
{
 "id": 236,
 "name": "b"},
{
 "id": 376,
 "name": "c"},
{
 "id": 253,
 "name": "d"},
{
 "id": 235,
 "name": "e"},
{
  "id": 24,
  "name": "f"}
];

function dynamicSort(property) {
   return function(a, b) {
       return (a[property] < b[property]) ? -1 : (a[property] > b[property]) ? 1 : 0;
   }
}

items.sort(dynamicSort('name')).sort(dynamicSort('id'));
console.log(items);
items.sort(dynamicSort('id')).sort(dynamicSort('name')); 
console.log(items);  

【讨论】:

    【解决方案3】:

    如果您的意思是您希望它们按 id 排序,并且如果 id 匹配,您希望它们按 name 排序然后使用:

    items.sort(function(a, b) {
        if (a.id !== b.id) {
            return a.id - b.id
        }
        if (a.name === b.name) {
          return 0;
        }
        return a.name > b.name ? 1 : -1;
    });
    

    否则你的问题不清楚。

    【讨论】:

      【解决方案4】:

      您的问题是如何对字母进行排序。
      a.name - b.name

      没有按照你的想法做。它没有按字典顺序评估它们。 替换为

      a.name &lt; b.name ? -1 : 1;

      【讨论】:

      • 如果名称相同,为什么您的代码返回 1?它应该返回0
      • 你是对的。这样做并不能保证相等的元素将保留其原始顺序。
      【解决方案5】:

      我在 Chrome 中没有看到任何错误,但它没有正确排序。

      如果我将您的排序代码更改为:

      var firstRun = items.sort(function(a, b) {
          return (a.id - b.id);
      });
      var secondRun = firstRun.sort(function(a, b) {
          return (a.name - b.name);
      });
      
      console.log(secondRun);​
      

      我相信它的排序正确。您的示例实际上并不需要进行第二次排序,因为每个数字(id)都不同。但是当我让 b、d 和 e 的 ID 都为 235 时,一切正常。

      【讨论】:

        猜你喜欢
        • 2021-12-28
        • 1970-01-01
        • 2019-01-26
        • 1970-01-01
        • 2019-06-15
        • 2018-11-02
        • 2013-11-02
        相关资源
        最近更新 更多