通过Javascript迭代复杂JSON对象的最简单方法

时间:2013-06-19 13:08:26

标签: javascript jquery json javascript-framework

我正在使用具有一些奇怪结构的JSON数据,例如:

{
    "RESULT": 
    {
        "COLUMNS": ["ID","name","ENABLED","perms","vcenabled","vcvalue","checkenabled","checkvalue","indxenabled","indxvalue"],
        "DATA": [
                    [7,"Site-A", 1, "1,2", 1, 1, 1, 0, 0, 0],
                    [15,"Site-B", 1, "1,2,3,4", 1, 1, 1, 0, 0, 0]
        ]
    },
    "ERROR": 0
}

我想创建一些JavaScript,将这些数据重组为正确的JSON结构,以便“Column”数组值成为“DATA”数组值的键。因此,在运行JS进程后,数据类似于以下内容:

[
  {"ID":7,"name":"Site-A","ENABLED":1,"perms":"1,2","vcenabled":1,"vcvalue":1,"checkenabled":1,"checkvalue":1,"indxenabled":1,"indxvalue":1},
  {"ID":15,"name":"Site-B","ENABLED":1,"perms":"1,2","vcenabled":1,"vcvalue":1,"checkenabled":1,"checkvalue":1,"indxenabled":1,"indxvalue":1}

]

完成JSON重组的JavaScript最佳实践是什么?我可以使用JS框架(如JQuery,Foundation JS,等等......)完成此任务吗?

7 个答案:

答案 0 :(得分:4)

使用Underscore,这是一个单行:

var formatted = _.map(orig.RESULT.DATA, _.partial(_.object, orig.RESULT.COLUMNS));

使用普通的javascript(不太优雅但更快),它将是

var formatted = [],
    data = orig.RESULT.DATA,
    cols = orig.RESULT.COLUMNS,
    l = cols.length;
for (var i=0; i<data.length; i++) {
    var d = data[i],
        o = {};
    for (var j=0; j<l; j++)
        o[cols[j]] = d[j];
    formatted.push(o);
}

答案 1 :(得分:2)

您可以使用下划线数组函数执行此任务

http://underscorejs.org/#arrays

使用对象功能会有所帮助 http://underscorejs.org/#object

来自文档: _.object(list,[values]) 将数组转换为对象。传递一个[key,value]对列表,或一个键列表,以及一个值列表..示例:

_.object(['moe', 'larry', 'curly'], [30, 40, 50]);
 => {moe: 30, larry: 40, curly: 50}

这是JSfiddle的解决方案 http://jsfiddle.net/rayweb_on/kxR88/1/

并且代码对于此特定方案看起来像这样。

 var plain = {
"RESULT": 
{
    "COLUMNS": ["ID","name","ENABLED","perms","vcenabled","vcvalue","checkenabled","checkvalue","indxenabled","indxvalue"],
    "DATA": [
                [7,"Site-A", 1, "1,2", 1, 1, 1, 0, 0, 0],
                [15,"Site-B", 1, "1,2,3,4", 1, 1, 1, 0, 0, 0]
    ]
},
"ERROR": 0
},

formatted = [];

_.each(plain.RESULT.DATA, function(value) {
    var tmp = {};
     tmp = _.object(plain.RESULT.COLUMNS,value)
    formatted.push(tmp);
});

 console.log(formatted);

答案 2 :(得分:2)

newjson是你的新对象,j是你的json,

代码非常快,因为它缓存了legth并且不使用push。

因为它是纯粹的javascript,它比所有库都要快。

var j={
 "RESULT":{
  "COLUMNS":[
   "ID",
   "name",
   "ENABLED",
   "perms",
   "vcenabled",
   "vcvalue",
   "checkenabled",
   "checkvalue",
   "indxenabled",
   "indxvalue"
  ],
  "DATA":[
   [7,"Site-A", 1, "1,2", 1, 1, 1, 0, 0, 0],
   [15,"Site-B", 1, "1,2,3,4", 1, 1, 1, 0, 0, 0]
  ]
 },
 "ERROR": 0
}

var newjson=[],d=j.RESULT.COLUMNS.length;
for(var a=0,b=j.RESULT.DATA.length;a<b;a++){
 for(var c=0,tmpObj={};c<d;c++){
  tmpObj[j.RESULT.COLUMNS[c]]=j.RESULT.DATA[a][c];
 }
 newjson[a]=tmpObj;
}

console.log(newjson);

基于Bergi的回答你也可以使用while--循环。

var orig={
 "RESULT":{
  "COLUMNS":[
   "ID",
   "name",
   "ENABLED",
   "perms",
   "vcenabled",
   "vcvalue",
   "checkenabled",
   "checkvalue",
   "indxenabled",
   "indxvalue"
  ],
  "DATA":[
   [7,"Site-A", 1, "1,2", 1, 1, 1, 0, 0, 0],
   [15,"Site-B", 1, "1,2,3,4", 1, 1, 1, 0, 0, 0]
  ]
 },
 "ERROR": 0
}

var formatted = [],
data = orig.RESULT.DATA,
cols = orig.RESULT.COLUMNS,
l = cols.length,
f = data.length;

while (f--) {
  var d = data[f],
      o = {},
      g = l;
  while (g--) {
    o[cols[g]] = d[g];
  }
  formatted[f] = o;
}

答案 3 :(得分:1)

使用underscorejs尝试此操作。

var plain = {
    "RESULT": 
    {
        "COLUMNS": ["ID","name","ENABLED","perms","vcenabled","vcvalue","checkenabled","checkvalue","indxenabled","indxvalue"],
        "DATA": [
                [7,"Site-A", 1, "1,2", 1, 1, 1, 0, 0, 0],
                [15,"Site-B", 1, "1,2,3,4", 1, 1, 1, 0, 0, 0]
        ]
    },
    "ERROR": 0
}
   , formatted = [];

_.each(plain.RESULT.DATA, function(value) {
    var tmp = {};
    _.each(value, function(parameter, pos) {
        tmp[plain.RESULT.COLUMNS[pos]] = parameter;
    });
    formatted.push(tmp);
});

console.log(formatted);

http://jsfiddle.net/kxR88/

答案 4 :(得分:1)

实际上,您可以将Array#map用于数组,Array#reduce用于具有新属性的对象

var data = { RESULT: { COLUMNS: ["ID", "name", "ENABLED", "perms", "vcenabled", "vcvalue", "checkenabled", "checkvalue", "indxenabled", "indxvalue"], DATA: [[7, "Site-A", 1, "1,2", 1, 1, 1, 0, 0, 0], [15, "Site-B", 1, "1,2,3,4", 1, 1, 1, 0, 0, 0]] }, ERROR: 0 },
    result = data.RESULT.DATA.map(function (a) {
        return a.reduce(function (o, d, i) {
            o[data.RESULT.COLUMNS[i]] = d;
            return o;
        }, {});
    });

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

使用ES6,您可以将Object.assignspread syntax ...一起使用。

Object.assign为给定对象添加属性并返回此对象。

传播语法...接受一个数组并将元素作为参数插入到函数中。

var data = { RESULT: { COLUMNS: ["ID", "name", "ENABLED", "perms", "vcenabled", "vcvalue", "checkenabled", "checkvalue", "indxenabled", "indxvalue"], DATA: [[7, "Site-A", 1, "1,2", 1, 1, 1, 0, 0, 0], [15, "Site-B", 1, "1,2,3,4", 1, 1, 1, 0, 0, 0]] }, ERROR: 0 },
    result = data.RESULT.DATA.map(a =>
        Object.assign(...data.RESULT.COLUMNS.map((k, i) => ({ [k]: a[i] }))));

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

答案 5 :(得分:0)

使用JQuery:

function jsonToObj(json){
   return jQuery.parseJSON(JSON.stringify(json));
}

例如,在GET请求之后,服务器发送了一个复杂的对象

  $.get("/Files/-2", function (rxData, status) {

      var obj = jsonToObj(rxData);
      console.log(obj);
  });

已登录的控制台,可以通过Chrome的Web开发人员(F12)浏览,在我的情况下,如下所示:

image showing nested levels

答案 6 :(得分:0)

通过简单的JS,您的解决方案应如下所示:

var yourObj = {
  "RESULT": {
    "COLUMNS": ["ID","name","ENABLED","perms","vcenabled","vcvalue","checkenabled","checkvalue","indxenabled","indxvalue"],
    "DATA": [
      [7,"Site-A", 1, "1,2", 1, 1, 1, 0, 0, 0],
      [15,"Site-B", 1, "1,2,3,4", 1, 1, 1, 0, 0, 0]
    ]
  },
  "ERROR": 0
}

//Solution

var finalARR = [];

var colLength = yourObj.RESULT.COLUMNS.length;
var dataLength = yourObj.RESULT.DATA.length;

for (var i = 0; i < dataLength; i++) {
  var finalJSON = {};
  for (var j = 0; j < colLength; j++) {
    finalJSON[yourObj.RESULT.COLUMNS[j]] = yourObj.RESULT.DATA[i][j];
  }
  finalARR[i] = finalJSON;
}

console.log(finalARR);