3

我正在使用具有一些奇怪结构的 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 结构,以便“列”数组值成为“数据”数组值的键。因此,在运行 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 最佳实践是什么?我可以使用 JQuery、Foundation JS 等 JS 框架来完成这项任务吗?

4

7 回答 7

5

使用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);
}
于 2013-06-19T15:54:08.253 回答
3

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;
}
于 2013-06-19T13:25:04.930 回答
3

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

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);
于 2013-06-19T13:22:41.023 回答
2

使用 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/

于 2013-06-19T13:30:54.783 回答
2

实际上,您可以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.assignwith spread 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; }

于 2017-09-05T10:28:26.763 回答
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);

于 2020-07-27T11:46:42.407 回答
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 Developer (F12) 进行探索,在我的例子中是这样的:

显示嵌套级别的图像

于 2019-10-10T14:36:34.240 回答