如何更改JSON中字段的顺序

时间:2013-05-14 11:56:22

标签: json node.js

场景:请考虑我有一个JSON文档,如下所示:

   {
     "name": "David",
     "age" : 78,
     "NoOfVisits" : 4
   }

问题:我想更改文档中字段的顺序/顺序,比如我想要ageNoOfVisits&最后name

截至目前,我正在将值存储在临时变量中,删除字段&重新创建相同的字段。由于重新分配不起作用:(

我是按照以下方式做到的:

    temp = doc["age"];
    delete doc['age'];
    doc["age"] = temp;

    temp = doc["NoOfVisits "];
    delete doc['NoOfVisits '];
    doc["NoOfVisits"] = temp;

    temp = doc["name"];
    delete doc['name'];
    doc["name"] = temp;

这样我就可以获得所需的有序JSON文档。这个要求是特殊的,但我仍然需要一些有效的解决方案

问题:有人可以通过有效的方式帮助实现同样的目标吗?

6 个答案:

答案 0 :(得分:17)

您可以使用JSON.stringify()

更改此设置

喜欢

var json = {     "name": "David",     "age" : 78,     "NoOfVisits" : 4   };
console.log(json);
//outputs - Object {name: "David", age: 78, NoOfVisits: 4}
//change order to NoOfVisits,age,name

var k = JSON.parse(JSON.stringify( json, ["NoOfVisits","age","name"] , 4));
console.log(k);
//outputs - Object {NoOfVisits: 4, age: 78, name: "David"} 

将所需的键顺序放入数组并提供给该函数。然后将结果解析回json。 这是一个sample fiddle

答案 1 :(得分:7)

对象没有特定的顺序。


更新

ES3 Specs

  

ECMAScript对象是无序的属性集合

ES5 Specs

  

未指定枚举属性的机制和顺序(第一个算法中的步骤6.a,第二个算法中的步骤7.a)。

     

枚举期间可以删除要枚举的对象的属性。如果删除枚举期间尚未访问的属性,则不会访问该属性。如果在枚举期间将新属性添加到要枚举的对象,则无法保证在活动枚举中访问新添加的属性。在任何枚举中不得多次访问属性名称。


然而。如果您想依赖V8实现顺序。

记住这一点。

当迭代一个Object时,V8按照以下方式迭代

  1. 数字属性按升序排列。 (虽然不能保证)
  2. 按插入顺序排列的非数字属性。
  3. 显示在以下example

    var a = {c:0,1:0,0:0};
    
    a.b = 0;
    a[3] = 0;
    a[2] = 0;
    
    for(var p in a) { console.log(p)};
    

    给出输出

    1. 0
    2. 1
    3. 2
    4. 3
    5. B'/ LI>
    6. C
    7. 如果您需要保证订单......

        

      你被迫使用两个独立的数组(一个用于键,另一个用于值),或者构建一个单属性对象数组等。

      (MDN)

答案 2 :(得分:4)

ECMA-262未指定枚举顺序。事实上的标准是匹配插入顺序,哪个V8也,但有一个例外:V8不保证数组索引的枚举顺序(即,可以解析为一个属性名称) 32位无符号整数)。

您的解决方案是有效的,这是在node.js中执行此操作的唯一方法,但您可以直接执行以下操作,而不是删除和插入新属性:

var previous = {
  "name": "David",
  "age" : 78,
  "NoOfVisits" : 4
};

var o = {};
o.age = previous.age;
o.NoOfVisits = previous.NoOfVisits;
o.name = previous.name;

如果只是做

,我还没有测试过
var o = {
  age: previous.age,
  NoOfVisits: previous.NoOfVisits,
  name: previous.name
};

也有效。

答案 3 :(得分:4)

尽管同意JS没有定义对象属性顺序的所有注释和答案,但我发现自己的问题有点类似,所以我会尝试回答你的问题:

  function reorder (order, obj) { 
    typeof order === 'string' && (order = order.split (/\s*,\s*/));
    return order.reduce (function (rslt, prop) {
        rslt[prop] = obj[prop];
        return rslt;   
      }, {});
  }

  reorder ("age,noOfVisits,name", {name: "David", age: 78, noOfVisits: 4});

它也可能用于从对象复制或提取属性的子集。

注意:我的问题需要以预定义的顺序处理属性,此函数也提供了执行此操作的基础。

答案 4 :(得分:1)

就JSON而言,没有顺序,不像每个对象都有索引的数组。如果你想要一个特定的订单,你需要做这样的事情把它变成一个数组:

var contact = {
 "name": "David",
 "age" : 78,
 "NoOfVisits" : 4
}
var arrcontact=[contact.age, contact.NoOfVisits, contact.name]

但是在这样做的过程中,你错过了JSON

答案 5 :(得分:0)

正如已经提到的那样,JavaScript object properties have no guaranteed order(想想看,有一个有意义吗?)。

如果您确实需要订购,可以使用数组:

[{"name" : "Dave"}, {"age" : 78}, {"NoOfVisits" : 4}]

或:

["Dave", 78, 4] // but here you have no idea what is happening

我不希望在我的代码中看到任何这些内容。 所以更好的想法是重新思考你想要实现的目标。