我有一些像这样的结构化JSON数据。假设这是可以通过以下方式互换的JSON.parse():
JSON.parse()
[ { "title": "pineapple", "uid": "ab982d34c98f" }, { "title": "carrots", "uid": "6f12e6ba45ec" } ]
我需要它看起来像这样,重新映射title到name,并uid以id与结果:
title
name
uid
id
[ { "name": "pineapple", "id": "ab982d34c98f" }, { "name": "carrots", "id": "6f12e6ba45ec" } ]
最明显的方法是这样的:
str = '[{"title": "pineapple","uid": "ab982d34c98f"},{"title": "carrots", "uid": "6f12e6ba45ec"}]'; var arr = JSON.parse(str); for (var i = 0; i<arr.length; i++) { arr[i].name = arr[i].title; arr[i].id = arr[i].uid; delete arr[i].title; delete arr[i].uid; } str = '[{"title": "pineapple","uid": "ab982d34c98f"},{"title": "carrots", "uid": "6f12e6ba45ec"}]'; var arr = JSON.parse(str); for (var i = 0; i<arr.length; i++) { arr[i].name = arr[i].title; arr[i].id = arr[i].uid; delete arr[i].title; delete arr[i].uid; } $('body').append("<pre>"+JSON.stringify(arr, undefined, 4)+"</pre>"); <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
一切都很好,但如果数组中有200,000个对象怎么办?这是很多处理开销。
有没有更有效的方法来重新映射键名? 可能不会遍历整个对象数组?如果您的方法更有效,请提供证明/参考。
正如我在评论中已经提到的那样,如果可以对对象的值进行某些假设,则可以使用正则表达式替换键,例如:
str = str.replace(/"title":/g, '"name":');
它不是“干净”的,但是可以更快地完成工作。
如果仍然必须解析JSON,则一种更结构化的方法是将 reviver 函数传递给JSON.parse JSON,这样您就可以避免对数组进行额外传递。不过,这可能取决于引擎的实现方式JSON.parse(也许它们首先解析整个字符串,然后使用reviver函数进行第二遍处理,在这种情况下,您将无法获得任何好处)。
JSON.parse
var arr = JSON.parse(str, function(prop, value) { switch(prop) { case "title": this.name = value; return; case "uid": this.id = value; return; default: return value; } });
基准测试,使用下面的Node.js脚本进行3次测试:
1389822740739: Beginning regex rename test 1389822740761: Regex rename complete // 22ms, 22ms, 21ms 1389822740762: Beginning parse and remap in for loop test 1389822740831: For loop remap complete // 69ms, 68ms, 68ms 1389822740831: Beginning reviver function test 1389822740893: Reviver function complete // 62ms, 61ms, 60ms
看起来regex(在这种情况下)是最有效的,但是在尝试使用正则表达式解析JSON时要小心
测试脚本,加载OP的示例JSON的100,230行:
fs = require('fs'); fs.readFile('test.json', 'utf8', function (err, data) { if (err) { return console.log(err); } console.log(new Date().getTime() + ": Beginning regex rename test"); var str = data.replace(/"title":/g, '"name":'); str = str.replace(/"uid":/g, '"id":'); JSON.parse(str); console.log(new Date().getTime() + ": Regex rename complete"); console.log(new Date().getTime() + ": Beginning parse and remap in for loop test"); var arr = JSON.parse(data); for (var i = 0; i < arr.length; i++) { arr[i].name = arr[i].title; arr[i].id = arr[i].uid; delete arr[i].title; delete arr[i].uid; } console.log(new Date().getTime() + ": For loop remap complete"); console.log(new Date().getTime() + ": Beginning reviver function test"); var arr = JSON.parse(data, function (prop, value) { switch (prop) { case "title": this.name = value; return; case "uid": this.id = value; return; default: return value; } }); console.log(new Date().getTime() + ": Reviver function complete"); });