按键排序JavaScript对象

839
我需要按键名对JavaScript对象进行排序。
因此以下内容:
{ 'b' : 'asdsad', 'c' : 'masdas', 'a' : 'dsfdsfsdf' }

将变成:

{ 'a' : 'dsfdsfsdf', 'b' : 'asdsad', 'c' : 'masdas' }

3
可能是重复的问题:在Javascript中对JSON对象进行排序 - abraham
71
在2011年(发布此问题时),ECMAScript规范指出JavaScript对象没有内在顺序——观察到的顺序取决于具体实现,因此不能依赖它。然而,事实证明所有JavaScript引擎都实现了更多或更少相同的语义,因此这些语义现在已在ES6中标准化。因此,许多下面的答案过去是正确的,符合规范,但现在不再正确。 - Mathias Bynens
1
简单来说,当您需要比较或哈希结果时,请使用排序的 stringify:https://www.npmjs.com/package/json-stable-stringify - exebook
7
请注意,自从 Object.entriesObject.fromEntries 被添加到 JS 中以来,可以使用一个漂亮的一行代码实现此操作:Object.fromEntries(Object.entries(obj).sort()) - Mike 'Pomax' Kamermans
递归按键对JavaScript对象进行排序 - https://dev59.com/64Hba4cB1Zd3GeqPPlKn#73160202 - 即对对象及其包含的对象进行排序 - danday74
显示剩余5条评论
38个回答

2

一句话概括:

Object.entries(unordered)
  .sort(([keyA], [keyB]) => keyA > keyB)
  .reduce((obj, [key,value]) => Object.assign(obj, {[key]: value}), {})

2
您可以这样排序:
Object.fromEntries(Object.entries(obj).sort(([a],[b]) => a.localeCompare(b)))

1

使用纯JavaScript对对象进行排序的方法。这是我所知道的唯一能处理负数的答案。此函数用于排序数字对象。

输入 obj = {1000: {}, -1200: {}, 10000: {}, 200: {}};

function osort(obj) {
var keys = Object.keys(obj);
var len = keys.length;
var rObj = [];
var rK = [];
var t = Object.keys(obj).length;
while(t > rK.length) {
    var l = null;
    for(var x in keys) {
        if(l && parseInt(keys[x]) < parseInt(l)) {
            l = keys[x];
            k = x;
        }
        if(!l) { // Find Lowest
            var l = keys[x];
            var k = x;
        }
    }
    delete keys[k];
    rK.push(l);
}

for (var i = 0; i < len; i++) {

    k = rK[i];
    rObj.push(obj[k]);
}
return rObj;
}

输出将是一个由这些数字排序的对象,新键从0开始。

1

我喜欢上面的答案,但它不起作用:

/**
 * Return an Object sorted by it's Key
 */
var sortObjectByKey = function(obj){
    var keys = [];
    var sorted_obj = {};

    for(var key in obj){
        if(obj.hasOwnProperty(key)){
            keys.push(key);
        }
    }

    // sort keys
    keys.sort();

    // create new array based on Sorted Keys
    jQuery.each(keys, function(i, key){
        sorted_obj[key] = obj[key];
    });

    return sorted_obj;
};

看起来排序后的对象没有顺序保证,因此使用映射表似乎更合适。我最终将对象更改为映射表,类似于以下内容:

/**
 * Return an Object sorted by it's Key
 */
var sortObjectByKey = function(obj){
    var keys = [];
    let sorted_map = new Map();

    for(var key in obj){
        if(obj.hasOwnProperty(key)){
            keys.push(key);
        }
    }

    // sort keys
    keys.sort();

    // create new map based on Sorted Keys
    keys.forEach(key => {
        sorted_map.set(key, obj[key]);
    });

    return sorted_map;
};

你为什么没有使用 Object.keys(obj) 而是用了 for(var key in obj){ if(obj.hasOwnProperty(key)){ keys.push(key); }} - Tomás

1
最好的方法是:
 const object =  Object.keys(o).sort().reduce((r, k) => (r[k] = o[k], r), {})

 //else if its in reverse just do 

 const object = Object.keys(0).reverse ()

你可以先将类似数组的对象转换为真正的数组,然后使用 .reverse() 方法:
Object.assign([], {1:'banana', 2:'apple', 
3:'orange'}).reverse();
// [ "orange", "apple", "banana", <1 empty slot> ]

在这里出现空槽是因为你的第一个索引是1而不是0。你可以用.length--或.pop()来移除空槽。
或者,如果你想借用.reverse并在同一对象上调用它,那么它必须是一个完全类似数组的对象。也就是说,它需要一个长度属性:
Array.prototype.reverse.call({1:'banana', 2:'apple', 
3:'orange', length:4});
// {0:"orange", 1:"apple", 3:"banana", length:4}

请注意,它将返回完全类似于数组的对象,因此它不是真正的数组。然后,您可以使用delete删除长度属性。

1

只是为了简化并使Matt Ball的回答更加清晰

//your object
var myObj = {
    b : 'asdsadfd',
    c : 'masdasaf',
    a : 'dsfdsfsdf'
  };

//fixed code
var keys = [];
for (var k in myObj) {
  if (myObj.hasOwnProperty(k)) {
    keys.push(k);
  }
}
keys.sort();
for (var i = 0; i < keys.length; i++) {
  k = keys[i];
  alert(k + ':' + myObj[k]);
}


1

不确定这是否回答了问题,但这正是我所需要的。

Maps.iterate.sorted = function (o, callback) {
    var keys = Object.keys(o), sorted = keys.sort(), k; 
    if ( callback ) {
            var i = -1;
            while( ++i < sorted.length ) {
                    callback(k = sorted[i], o[k] );
            }
    }

    return sorted;
}

被称为:
Maps.iterate.sorted({c:1, b:2, a:100}, function(k, v) { ... } ) 

0

所选答案未考虑嵌套的 JSON 对象情况。

要按键对具有嵌套子项的对象进行排序,需要递归地对该对象进行排序:

function sortObjectByKeyDeep(obj) {
  const sortedObj = {};
  const keys = Object.keys(obj).sort();

  for (let i = 0; i < keys.length; i++) {
    const key = keys[i];
    const value = obj[key];

    if (typeof value === "object" && !Array.isArray(value)) {
      sortedObj[key] = sortObjectByKeyDeep(value);
    } else if (Array.isArray(value)) {
      sortedObj[key] = value.map((item) =>
        typeof item === "object" ? sortObjectByKeyDeep(item) : item
      );
    } else {
      sortedObj[key] = value;
    }
  }

  return sortedObj;
}

测试用例:

const myObj = {
  c: 1,
  b: {
    d: 2,
    a: 3,
  },
  e: [
    {
      g: 4,
      f: 5,
    },
    {
      i: 6,
      h: 7,
    },
  ],
};

const sortedObj = sortObjectByKeyDeep(myObj);
console.log(sortedObj);
// Output: {b: {a: 3, d: 2}, c: 1, e: [{f: 5, g: 4}, {h: 7, i: 6}]}

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