有没有办法对 JavaScript 对象中的键进行排序/排序?

IT技术 javascript
2021-03-03 07:55:44

例如以下

var data = {
    'States': ['NSW', 'VIC'],
    'Countries': ['GBR', 'AUS'],
    'Capitals': ['SYD', 'MEL']
}
for (var item in data) {
    console.log(item);
}

印刷

States
Countries
Capitals

有没有办法按字母顺序排序以便打印

Capitals
Countries
States
6个回答

不在对象本身内:对象的属性集合是无序的。

您可以做的一件事是使用Object.keys(),并对数组进行排序,然后对其进行迭代。

Object.keys(data)
      .sort()
      .forEach(function(v, i) {
          console.log(v, data[v]);
       });

不支持 ECMAScript 第 5 版的浏览器的补丁(实现):

谢谢@squint。打字太快,思考太慢。:)
2021-04-20 07:55:44
这解决了我的问题,但我很想知道ifunction(v, i) 中的参数代表什么
2021-04-24 07:55:44
值得补充的是,如果您想要颠倒排序顺序,可以将 .sort() 替换为 .replace() 。此外, sort() 和 reverse() 接受比较函数作为参数,允许您微调排序。w3schools.com/jsref/jsref_sort.asp
2021-04-27 07:55:44
@WillCarron:这是当前迭代的数字索引。因此,如果有 3 个键,则在每次调用回调时i都会给出0, 1, 2因为i函数中没有使用它,所以可以安全地删除它,因为 JS 从不要求您为所有或任何传递的参数提供参数。使用浏览器中可用的日志记录工具,您可以检查应用程序中数据的值。console.log("The value of 'i' is:", i)
2021-05-12 07:55:44
@CharlesJaimet:不确定你的意思.replace()你的意思是.reverse()这确实可以使用,但前提是您希望当前顺序颠倒。如果要颠倒排序顺序,则必须先对其进行排序。.sort()方法确实接受一个函数,但.reverse()接受
2021-05-14 07:55:44

这是一个很好的功能解决方案:

基本上,

  1. 将密钥提取到列表中 Object.keys
  2. sort 按键
  3. 将列表减少回一个对象以获得所需的结果

ES5解决方案:

not_sorted = {b: false, a: true};

sorted = Object.keys(not_sorted)
    .sort()
    .reduce(function (acc, key) { 
        acc[key] = not_sorted[key];
        return acc;
    }, {});

console.log(sorted) //{a: true, b: false}

ES6 解决方案:

not_sorted = {b: false, a: true}

sorted = Object.keys(not_sorted)
    .sort()
    .reduce((acc, key) => ({
        ...acc, [key]: not_sorted[key]
    }), {})

console.log(sorted) //{a: true, b: false}

就在这里。不在 ECMAScript 标准范围内,但支持跨浏览器和 Node.js,并且显然稳定。请参阅https://stackoverflow.com/a/23202095/645715

编辑:这将返回一个键被排序的对象。您可以使用Object.keys(...)从对象中获取有序键。

为什么要担心对象键顺序?差异在某些应用程序中可能很重要,例如使用xml2js解析 XML,它将XML 表示为嵌套对象,并使用 XML 标签作为哈希键。

有几个注意事项:

  • 看起来像整数的键首先出现并按数字顺序出现。
  • 看起来像字符串的键按插入顺序出现在下一个。
  • 此订单由 Object.keys(obj)
  • 所报告的顺序for (var key in obj) {...}在 Safari、Firefox 中可能有所不同

该函数返回一个对象,其中包含按字母顺序插入的排序键:

function orderKeys(obj, expected) {

  var keys = Object.keys(obj).sort(function keyOrder(k1, k2) {
      if (k1 < k2) return -1;
      else if (k1 > k2) return +1;
      else return 0;
  });

  var i, after = {};
  for (i = 0; i < keys.length; i++) {
    after[keys[i]] = obj[keys[i]];
    delete obj[keys[i]];
  }

  for (i = 0; i < keys.length; i++) {
    obj[keys[i]] = after[keys[i]];
  }
  return obj;
}

这是一个快速测试:

var example = { 
      "3": "charlie",
      "p:style": "c",
      "berries": "e",
      "p:nvSpPr": "a",
      "p:txBody": "d",
      "apples": "e",
      "5": "eagle",
      "p:spPr": "b"
    }

var obj = orderKeys(example);

这返回

{ '3': 'charlie',
  '5': 'eagle',
  apples: 'e',
  berries: 'e',
  'p:nvSpPr': 'a',
  'p:spPr': 'b',
  'p:style': 'c',
  'p:txBody': 'd' }

然后,您可以按以下方式获取订购的密钥:

Object.keys(obj) 

哪个返回

["3", "5", "apples", "berries", "p:nvSpPr", "p:spPr", "p:style", "p:txBody"]
是的,谢谢。在这样的事情上效果很好:{2018-04-02 05:46:51: "0.0000003900", 2018-04-02 04:46:48: "0.0000004000", 2018-04-03 05:03:03: 0.0000004000", 2018-04-02 06:46:55: "0.0000003900", 2018-04-02 02:46:34: "0.0000004000", …}2018-09:004:03", …}2018-004:06" -04-02 02:46:34: "0.0000004000"2018-04-02 03:46:42: "0.0000003900"2018-04-02 04:46:48: "0.000000040204:-2040004" 51: “0.0000003900” 2018年4月2日6点46分55秒“0.0000003900” 2018年4月3日00:00:32: “0.0000003900” 2018年4月3日1点零零分35秒: “0.0000004000”:对象
2021-04-17 07:55:44
@VaelVictus 很好,它是从单元测试中复制粘贴的,现在不需要了。
2021-04-18 07:55:44
非常感谢。expected在这里做什么不提供时它不会抱怨。
2021-04-21 07:55:44

您也可以通过这种方式对其进行排序。

const data = {
  States: ['NSW', 'VIC'],
  Countries: ['GBR', 'AUS'],
  Capitals: ['SYD', 'MEL']
}

const sortedObject = Object.fromEntries(Object.entries(data).sort())

我无法详细解释它为什么有效,但显然它完美无缺:) 如果您不相信我,请尝试自己:D

请注意,您的浏览器或 Node.js 版本应支持 Object.fromEntries

对于浏览器兼容性检查此页面底部

对于 Node,它适用于 12 及更高版本。对于来自 v1.1 的 Deno。

这是使用lodash对对象的键进行排序的单行代码

_.chain(obj).toPairs().sortBy(0).fromPairs().value()

使用您的示例数据:

var data = {
    'States': ['NSW', 'VIC'],
    'Countries': ['GBR', 'AUS'],
    'Capitals': ['SYD', 'MEL']
}
data = _.chain(data)
  .toPairs() // turn the object into an array of [key, value] pairs
  .sortBy(0) // sort these pairs by index [0] which is [key]
  .fromPairs() // convert array of pairs back into an object {key: value}
  .value() // return value
/*
{
  Capitals: [ 'SYD', 'MEL' ],
  Countries: [ 'GBR', 'AUS' ],
  States: [ 'NSW', 'VIC' ]
}
*/