按属性名称对JavaScript对象进行排序

75

我已经寻找了一段时间,想要一种可以对这样的JavaScript对象进行排序的方法:

{
    method: 'artist.getInfo',
    artist: 'Green Day',
    format: 'json',
    api_key: 'fa3af76b9396d0091c9c41ebe3c63716'
}

并按名称字母顺序排序,得到:

{
    api_key: 'fa3af76b9396d0091c9c41ebe3c63716',
    artist: 'Green Day',
    format: 'json',
    method: 'artist.getInfo'
}

我找不到能够实现这个功能的代码,有谁可以给我一些帮助吗?


不错的教程,介绍如何对复杂的JS对象进行排序。http://www.highdots.com/forums/javascript/re-sorting-json-data-270187.html
  • 另一个例子 --- 如果您想了解详细信息,这里有一个完整的sort函数参考:https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Objects/Array/sort - 最后一次编辑,我发誓!
- Kelly Robins
我遇到的问题是这些文章展示了如何对一个对象数组进行排序。我正在尝试对一个充满对象的对象进行排序。如果是这样的话,同样的例子是否适用于我的情况?如果可以的话,您能否提供一个例子呢?抱歉,我只是在这个问题上真的卡住了:s - matto1990
7
这是一个古老的问题,但我是个语言纠正者,所以就算是第一千亿次:没有所谓的JSON对象——至少不是你所指的那种。有JavaScript对象和JSON字符串。 - Zac B
2
因为艺术价值而点赞。 :D - jofftiquez
ES6有更好的答案,可以在https://dev59.com/4m035IYBdhLWcg3wW-v0找到。 - aleung
@matto1990 你尝试过使用 stacksort 吗? :) - Michael M.
7个回答

101

更新自评论:

这个回答已经过时了。在ES6中,对象键现在是有序的。请参阅此问题了解最新的答案

根据定义,对象键的顺序是未定义的,因此您可能无法以未来可靠的方式进行操作。相反,您应该考虑在实际向用户显示对象时对这些键进行排序。无论内部使用的排序顺序如何,都不会真正重要。

按照惯例,大多数浏览器将保留对象键的顺序,按照它们添加到对象中的顺序排列。因此,您可以这样做,但不要指望它总是有效:

function sortObject(o) {
    var sorted = {},
    key, a = [];

    for (key in o) {
        if (o.hasOwnProperty(key)) {
            a.push(key);
        }
    }

    a.sort();

    for (key = 0; key < a.length; key++) {
        sorted[a[key]] = o[a[key]];
    }
    return sorted;
}

2
你应该绝对使用数组来完成这个任务。 - Breton
如果 (o.hasOwnProperty(key)) {'这并不是必要的,还有关于多级对象或包含对象的数组,或者反过来的情况呢?虽然这是一个很好的起点,但我的方法一开始也类似,然后我对其进行了升级... http://stamat.wordpress.com/2013/07/03/javascript-object-ordered-property-stringify/ - stamat
为了对键进行不区分大小写的排序,请将a.sort();替换为a.sort(function (a, b) { return a.toLowerCase().localeCompare(b.toLowerCase());}); - Sebastian
4
这个答案已经过时了。在 ES6 中,对象键现在是有序的。请参考 这个问题 以获得最新的答案! - Nino Filiu
10
那个从未完成其任务的 StackSort 回答… - val is still with Monica
显示剩余4条评论

13

这个函数接受一个对象并返回一个按键排序的数组,其格式为[key,value]的数组。

function (o) {
   var a = [],i;
   for(i in o){ 
     if(o.hasOwnProperty(i)){
         a.push([i,o[i]]);
     }
   }
   a.sort(function(a,b){ return a[0]>b[0]?1:-1; })
   return a;
}

对象数据结构没有明确定义的顺序。从数学上讲,一个对象中的键集合是一个无序集合,并且应该被视为这样处理。 如果您想定义顺序,应该使用数组,因为假设具有顺序的数组是您可以依赖的假设。一个拥有某种顺序的对象是留给实现随意决定的。


5

5

这里有一条简单易懂的命令。

Array.prototype.reduce()

let data = {
    method: 'artist.getInfo',
    artist: 'Green Day',
    format: 'json',
    api_key: 'fa3af76b9396d0091c9c41ebe3c63716'
};

let sorted = Object.keys(data).sort().reduce( (acc, currValue) => {
    acc[currValue] = data[currValue];
    return acc;
}, {});

console.log(sorted);

祝你好运!


2
更简洁的写法:Object.keys(data).sort().reduce((o, key) => ({...o, [key]: data[key]}), {}) - MAMY Sébastien

3
// if ya need old browser support
Object.keys = Object.keys || function(o) {  
var result = [];  
for(var name in o) {  
    if (o.hasOwnProperty(name))  
      result.push(name);  
}  
    return result;  
};

var o = {c: 3, a: 1, b: 2};
var n = sortem(o);

function sortem(old){
  var newo = {}; Object.keys(old).sort().forEach(function(k) {new[k]=old[k]});
  return newo;
}

// deep
function sortem(old){
  var newo = {}; Object.keys(old).sort().forEach(function(k){ newo[k]=sortem(old[k]) });
  return newo;
}
sortem({b:{b:1,a:2},a:{b:1,a:2}})

非常好和流畅,但不幸的是Object.keys()在IE<9中不被支持,在任何IE>=9的Quirks模式下也不被支持。请参见MSDN的IE Dev Center - Jpsy
已添加polyfill到上面的答案。 - C B
如果你的意思是对对象进行深度排序,我已经在上面编辑了答案。'new' 是一个打字错误。 - C B

2

ES5 兼容:

function sortByKey(obj) {
    var keys = Object.keys(obj);
    keys.sort();
    var sorted = {};
    for (var i = 0; i < keys.length; i++) {
        var key = keys[i];
        sorted[key] = obj[key];
    }
    return sorted;
}

0

应该谨慎使用此功能,因为您的代码不应依赖于对象属性的顺序。如果只是为了呈现(或仅仅是为了好玩!),您可以像这样深度排序属性:

function sortObject(src) {
  var out;
  if (typeof src === 'object' && Object.keys(src).length > 0) {
    out = {};
    Object.keys(src).sort().forEach(function (key) {
      out[key] = sortObject(src[key]);
    });
    return out;
  }
  return src;
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接