Easiest way to interate over a complex JSON object via Javascript

☆樱花仙子☆ 提交于 2019-12-18 09:39:31

问题


I'm consuming JSON data that has a bit of a weird structure for example:

{
    "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
}

I would like to create some JavaScript that would restructure this data to proper JSON structures so that the "Column" array values become the keys for the "DATA" array's values. So after a JS process is run the data resembles the following:

[
  {"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}

]

What are the JavaScript best practices for accomplishing the JSON restructuring? Could I accomplish this task using a JS framework like JQuery, Foundation JS, ect... ?


回答1:


newjson is your new object, j is your json,

code is very fast as it caches the legth and don't uses push.

And as it's pure javascript it's faster than all the libraries.

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);

based on Bergi's response u can also use the while-- loop.

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;
}



回答2:


Using Underscore, it's a one-liner:

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

With plain javascript (less elegant but faster), it would be

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);
}



回答3:


you can use underscore Array functions for this task

http://underscorejs.org/#arrays

uusing the object function would be helpful http://underscorejs.org/#object

from the documentation : _.object(list, [values]) Converts arrays into objects. Pass either a single list of [key, value] pairs, or a list of keys, and a list of values ..the example:

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

here is the JSfiddle with the solution http://jsfiddle.net/rayweb_on/kxR88/1/

and the code looks like this for this specific scenario.

 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);



回答4:


Try this using 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/




回答5:


Actually, you could use a combination of Array#map for the array and Array#reduce for the objects with the new properties

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; }

With ES6, you could use Object.assign with spread syntax ....

Object.assign adds properties to the given object and returns this object.

Spread syntax ... takes an array and insert the elements as parameters to the function.

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; }



回答6:


Using JQuery:

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

For example, after a GET request the server send a complex object

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

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

Logged in console, can be explored through Chrome's Web Developer (F12), in my case looks like this:

image showing nested levels



来源:https://stackoverflow.com/questions/17192051/easiest-way-to-interate-over-a-complex-json-object-via-javascript

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!