通过 Javascript 迭代复杂 JSON 对象的最简单方法
Posted
技术标签:
【中文标题】通过 Javascript 迭代复杂 JSON 对象的最简单方法【英文标题】:Easiest way to interate over a complex JSON object via Javascript 【发布时间】:2013-06-16 00:51:08 【问题描述】:我正在使用的 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 最佳实践是什么?我可以使用 JQuery、Foundation JS 等 JS 框架来完成这项任务吗?
【问题讨论】:
您可以通过一个简单的循环来完成此操作。创建一个空对象,遍历COLUMNS
,从DATA
获取数据并填充新对象。
@claustrofob: 两个 为简单起见循环:-)
【参考方案1】:
使用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);
【讨论】:
【参考方案2】:newjson 是你的新对象,j 是你的 json,
代码非常快,因为它会缓存长度并且不使用推送。
因为它是纯 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;
【讨论】:
为什么你认为不使用推送会更好?顺便说一句,代码很慢,因为它不缓存相关的东西。 newjson[a]=tmpObj;比 newjson.push(tmpObj) 快。你想缓存什么? 好的,如果您已经拥有index
会更好,但arr.push(x)
和arr[arr.length] = x
之间没有相关区别。有关详细分析,请参阅***.com/q/614126 - 应该使用更清晰易读的内容:-)
jsperf.com/reformat-json 是的,这取决于浏览器,无论如何都可以很好地使用缓存 =)
我现在添加了一个while--循环;)【参考方案3】:
您可以为此任务使用下划线数组函数
http://underscorejs.org/#arrays
使用对象函数会很有帮助 http://underscorejs.org/#object
来自文档: _.object(列表,[值]) 将数组转换为对象。传递 [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);
【讨论】:
嗯,你真的应该使用适当的 array function :-)【参考方案4】:使用 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/
【讨论】:
你为什么使用慢速的each
函数而不是for循环?下划线方法看起来不同。
是的,你的下划线单行看起来更好。 _.partial
不错,没用过。【参考方案5】:
实际上,您可以将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.assign
和 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;
【讨论】:
【参考方案6】:使用 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) 进行探索,在我的例子中是这样的:
image showing nested levels
【讨论】:
【参考方案7】:通过简单的 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);
【讨论】:
以上是关于通过 Javascript 迭代复杂 JSON 对象的最简单方法的主要内容,如果未能解决你的问题,请参考以下文章
我制作了一个JavaScript对象,无法对其进行迭代,甚至无法访问其参数。我想念什么?
在 Javascript 中迭代 JSON 字符串的最快方法
Javascript - 使用 HTML 片段通过电子邮件发送 JSON 输出