问题描述
我有一些结构化的JSON数据。我们假设这是可以互换的,通过:
I have some structured JSON data like so. Let's assume this is interchangeable, via JSON.parse()
:
[
{
"title": "pineapple",
"uid": "ab982d34c98f"
},
{
"title": "carrots",
"uid": "6f12e6ba45ec"
}
]
我需要它看起来像这样,将 title
重新映射到 name
,以及 uid
到 id
,结果为:
I need it to look like this, remapping title
to name
, and uid
to id
with the result:
[
{
"name": "pineapple",
"id": "ab982d34c98f"
},
{
"name": "carrots",
"id": "6f12e6ba45ec"
}
]
最明显的方式这样做是这样的:
The most obvious way of doing it is like this:
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>
...或使用更复杂的东西(虽然不更有效率),如。
...or using something more complex (albeit not more efficient) like this.
这一切都很好,但是如果数组中有200,000个对象怎么办?这是很多处理开销。
This is all fine and dandy, but what if there were 200,000 objects in the array? This is a lot of processing overhead.
是否有更有效的方法来重新映射密钥名称?可能没有遍历整个对象数组?如果您的方法更有效,请提供证明/参考。
推荐答案
正如我在评论中已经提到的那样,如果您可以对对象的值做出某些假设,则可以使用正则表达式来替换键,例如:
As I already mentioned in the comments, if you can make certain assumptions about the values of the objects, you could use a regular expression to replace the keys, for example:
str = str.replace(/"title":/g, '"name":');
它不像干净,但它可能会更快地完成工作。
It's not as "clean", but it might get the job done faster.
如果你不得不解析JSON,更有条理的方法是您可以避免对阵列进行额外的传递。这可能取决于引擎如何实现 JSON.parse
(也许它们首先解析整个字符串,然后使用reviver函数进行第二次传递,在这种情况下你不会获得任何优势)。
If you have to parse the JSON anyway, a more structured approach would be to pass a reviver function to JSON.parse
and you might be able to avoid an additional pass over the array. This probably depends on how engine implement JSON.parse
though (maybe they parse the whole string first and then make a second pass with the reviver function, in which case you wouldn't get any advantage).
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次:
Benchmarks, using the Node.js script below to test 3 times:
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
出现好像正则表达式(在这种情况下)是最有效的,但。
It appears as if the regex (in this case) is the most efficient, but be careful when trying to parse JSON with regular expressions.
测试脚本,加载100,230行OP的样本JSON:
Test script, loading 100,230 lines of the OP's sample JSON:
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");
});
这篇关于在对象数组中有效地重命名/重新映射javascript / json对象键的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!