【问题标题】:Changing the order of the Object keys....更改对象键的顺序....
【发布时间】:2011-08-05 16:51:55
【问题描述】:
var addObjectResponse = [{
    'DateTimeTaken': '/Date(1301494335000-0400)/',
    'Weight': 100909.090909091,
    'Height': 182.88,
    'SPO2': '222.00000',
    'BloodPressureSystolic': 120,
    'BloodPressureDiastolic': 80,
    'BloodPressurePosition': 'Standing',
    'VitalSite': 'Popliteal',
    'Laterality': 'Right',
    'CuffSize': 'XL',
    'HeartRate': 111,
    'HeartRateRegularity': 'Regular',
    'Resprate': 111,    
    'Temperature': 36.6666666666667,
    'TemperatureMethod': 'Oral',    
    'HeadCircumference': '',    
}];

这是我从后端获取的示例对象,现在我想更改对象的顺序。我不想按名称或大小排序...我只想手动更改顺序...

【问题讨论】:

  • 您将收到该响应的错误,因为 'HeadCircumference': '',不应该有多余的逗号
  • 您想更改键/值对的顺序吗?为什么?
  • 按你想要的顺序写出来。您可以按您想要的顺序创建一个键数组并使用该数组访问对象

标签: javascript


【解决方案1】:

如果您从第一个对象创建一个新对象(如当前接受的答案所示),您将始终需要了解对象中的所有属性(维护噩梦)。

请改用Object.assign()

*这适用于现代浏览器——不适用于 IE 或 Edge

 let addObjectResponse = {
        'DateTimeTaken': '/Date(1301494335000-0400)/',
        'Weight': 100909.090909091,
        'Height': 182.88,
        'SPO2': '222.00000',
        'BloodPressureSystolic': 120,
        'BloodPressureDiastolic': 80,
        'BloodPressurePosition': 'Standing',
        'VitalSite': 'Popliteal',
        'Laterality': 'Right',
        'CuffSize': 'XL',
        'HeartRate': 111,
        'HeartRateRegularity': 'Regular',
        'Resprate': 111,    
        'Temperature': 36.6666666666667,
        'TemperatureMethod': 'Oral',    
        'HeadCircumference': '',    
    };

    // Create an object which will serve as the order template
    let objectOrder = {
        'HeartRate': null,
        'HeartRateRegularity': null,
    }

    addObjectResource = Object.assign(objectOrder, addObjectResource);

现在你要订购的两件物品已经排好序了,剩下的属性在它们下面。

现在您的对象将如下所示:

{           
            'HeartRate': 111,
            'HeartRateRegularity': 'Regular',
            'DateTimeTaken': '/Date(1301494335000-0400)/',
            'Weight': 100909.090909091,
            'Height': 182.88,
            'SPO2': '222.00000',
            'BloodPressureSystolic': 120,
            'BloodPressureDiastolic': 80,
            'BloodPressurePosition': 'Standing',
            'VitalSite': 'Popliteal',
            'Laterality': 'Right',
            'CuffSize': 'XL',
            'Resprate': 111,    
            'Temperature': 36.6666666666667,
            'TemperatureMethod': 'Oral',    
            'HeadCircumference': '',    
}

【讨论】:

  • 这对我很有用,除非键为零(数字为零)。无论如何,它永远是第一位的。
【解决方案2】:

我写了这个允许移动键的小算法,它就像 jQuery .insertAfter() 方法。您必须提供:

//currentKey: the key you want to move
//afterKey: position to move-after the currentKey, null or '' if it must be in position [0]
//obj: object


function moveObjectElement(currentKey, afterKey, obj) {
    var result = {};
    var val = obj[currentKey];
    delete obj[currentKey];
    var next = -1;
    var i = 0;
    if(typeof afterKey == 'undefined' || afterKey == null) afterKey = '';
    $.each(obj, function(k, v) {
        if((afterKey == '' && i == 0) || next == 1) {
            result[currentKey] = val; 
            next = 0;
        }
        if(k == afterKey) { next = 1; }
        result[k] = v;
        ++i;
    });
    if(next == 1) {
        result[currentKey] = val; 
    }
    if(next !== -1) return result; else return obj;
}

例子:

var el = {a: 1, b: 3, c:8, d:2 }
el = moveObjectElement('d', '', el); // {d,a,b,c}
el = moveObjectElement('b', 'd', el); // {d,b,a,c}

【讨论】:

  • 我喜欢让不可能的事情成为可能的人。
【解决方案3】:

您不能订购 JavaScript 对象键/值对。它以自己的内部格式存储,因此您永远不应该依赖它的顺序。在 JS 中,一切都是对象,甚至是数组。所以有时你可以在同时使用数组表示法和对象表示法时引入错误 (for x in var)

【讨论】:

  • 虽然这是真的,但这与现实世界的用法不同,其中模板通常通过循环对象属性来呈现。当你遍历它们时,它们有一个命令。更改此顺序是……脆弱的,但应该添加 IMO。
  • 在看到这个 MDN 页面之前,我也有同样的印象:developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… 第一行说 Map 对象包含键值对并记住键的原始插入顺序
  • 这个答案当时是正确的,但现在已经过时且不正确:您可以完全依赖从 ECMAScript 6 开始的对象键的顺序。它已成为 JavaScript 规范的一部分。请参阅@Tim Down 或此链接的答案:2ality.com/2015/10/property-traversal-order-es6.html
  • 现在可以对对象的属性进行排序了。
【解决方案4】:

2020 年更新

在 2011 年撰写本文时,以下答案是正确的。但是,从 ES6 开始,枚举顺序已被指定为语言的一部分。这是一篇很好的文章总结了这一点:https://2ality.com/2015/10/property-traversal-order-es6.html

原答案

JavaScript 中对象的属性没有顺序。在某些浏览器中似乎有一个顺序,但 ECMAScript 规范将对象属性枚举顺序定义为特定于实现的,因此您不应假设一个浏览器的行为与另一个浏览器的行为相同。例如,Chrome 不使用与其他一些浏览器相同的顺序:请参阅this lengthy bug report,了解有关此问题的尽可能多的讨论。

如果您需要特定的顺序,请使用一个数组或两个数组(一个用于键,一个用于值)。

【讨论】:

    【解决方案5】:

    你可以使用 Object.keys():

    var obj = {
        a: 1,
        b: 2,
        c: 4
    };
    
    var new_obj = {};
    
    Object.keys(obj)
    .sort(function(a, b) {
        /** Insert your custom sorting function here */
        return a - b;
    })
    .forEach(function(key) {
        new_obj[key] = obj[key];
    });
    
    obj = new_obj;
    

    【讨论】:

    • 我做了这样的事情,订单没有保留。
    【解决方案6】:

    我喜欢 Chamika Sandamal 的认可答案。这是一个简单的函数,它使用相同的逻辑,可以根据需要随意更改顺序。

    function preferredOrder(obj, order) {
        var newObject = {};
        for(var i = 0; i < order.length; i++) {
            if(obj.hasOwnProperty(order[i])) {
                newObject[order[i]] = obj[order[i]];
            }
        }
        return newObject;
    }
    

    你给它一个对象,和一个你想要的键名数组,然后返回一个按顺序排列的属性的新对象。

    var data = {
        c: 50,
        a: 25,
        d: 10,
        b: 30
    };
    
    data = preferredOrder(data, [
        "a",
        "b",
        "c",
        "d"
    ]);
    
    console.log(data);
    
    /*
        data = {
            a: 25,
            b: 30,
            c: 50,
            d: 10
        }
    */
    

    我正在从一个大的 JSON 对象复制并粘贴到 CMS 中,并且将源 JSON 重新组织成与 CMS 中的字段相同的顺序,这挽救了我的理智。

    【讨论】:

      【解决方案7】:

      如果您想手动重新排序。只需创建新对象并使用旧对象分配值。

      var newObject= [{
          'DateTimeTaken': addObjectResponse.DateTimeTaken,
          'Weight': addObjectResponse.Weight,
          'Height': addObjectResponse.Height,
          'SPO2': addObjectResponse.SPO2 
      }];
      

      【讨论】:

      • 那没有比原始对象更多的顺序。对象属性在 JavaScript 中没有一致的枚举顺序。
      • 可能有一个用例需要这样做,比如用模板库渲染一个对象
      • 对象属性do在javascript中的顺序是一致的,也就是添加的顺序。见Object.prototype.entries(someObject);
      • @JayDayZee I did look it up。 “Object.entries() 返回的数组的顺序不依赖于对象的定义方式。”
      • 有一个排序,但这个排序不一定是Object.entries使用的排序。顺序是整数键,按升序排列,然后是字符串键,按它们添加的顺序,然后是符号键,按它们添加的顺序。 (tc39.es/ecma262/…)。
      【解决方案8】:

      如果不想创建新对象,可以使用以下代码sn -p。

      function orderKey(obj, keyOrder) {
          keyOrder.forEach((k) => {
              const v = obj[k]
              delete obj[k]
              obj[k] = v
          })
      }
      

      这是一个代码笔:https://codepen.io/zhangyanwei/pen/QJeRxB

      【讨论】:

      • 这是一个优雅的解决方案,尤其是,因为如果发送的数据发生变化,它不会丢失键:值对。但是,您仍然需要了解所有键。 keyOrder 中未标识的任何键都将位于对象的前面。
      • 使用Object.assign() 将允许将未知的key:pairs 放置在底部。
      • 另外,遗憾的是,这不适用于数字键
      • 这个方法有点棘手。您应该对键使用排序数组,而不是更新对象。 - 那将是最安全的方法。
      【解决方案9】:

      我认为这在 JavaScript 中是不可能的。

      您可以创建一个数组,其中包含您订单中的字段名称,您可以遍历该数组并从实际对象中获取字段。

      【讨论】:

      • @John:我不明白你的评论。
      【解决方案10】:

      只需按照您喜欢的顺序引用对象键即可:

      aKeys = [
        addObjectResponse[0].DateTimeTaken,
        addObjectResponse[0].Weight,
        addObjectResponse[0].Height,
        ...etc...
      ]
      

      【讨论】:

        【解决方案11】:
        function orderKeys(obj, keys){
            const newObj = {};
            for(let key of keys){
                newObj[key] = obj[key];
            }
            return newObj;
        }
        

        【讨论】:

          猜你喜欢
          • 2021-12-23
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-06-04
          • 2019-07-16
          • 1970-01-01
          相关资源
          最近更新 更多