使用 node.js 遍历 JSON
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5829007/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Looping through JSON with node.js
提问by crawf
I have a JSON file which I need to iterate over, as shown below...
我有一个需要迭代的 JSON 文件,如下所示...
{
"device_id": "8020",
"data": [{
"Timestamp": "04-29-11 05:22:39 pm",
"Start_Value": 0.02,
"Abstract": 18.60,
"Editor": 65.20
}, {
"Timestamp": "04-29-11 04:22:39 pm",
"End_Value": 22.22,
"Text": 8.65,
"Common": 1.10,
"Editable": "true",
"Insert": 6.0
}]
}
The keys in data will not always be the same (i've just used examples, there are 20 different keys), and as such, I cannot set up my script to statically reference them to get the values.
数据中的键并不总是相同的(我刚刚使用了示例,有 20 个不同的键),因此,我无法将脚本设置为静态引用它们以获取值。
Otherwise I could state
否则我可以说
var value1 = json.data.Timestamp;
var value2 = json.data.Start_Value;
var value3 = json.data.Abstract;
etc
In the past i've used a simple foreach loop on the data node...
过去我在数据节点上使用了一个简单的 foreach 循环......
foreach ($json->data as $key => $val) {
switch($key) {
case 'Timestamp':
//do this;
case: 'Start_Value':
//do this
}
}
But don't want to block the script. Any ideas?
但不想阻止脚本。有任何想法吗?
回答by Van Coding
You can iterate through JavaScript objects this way:
您可以通过以下方式遍历 JavaScript 对象:
for(var attributename in myobject){
console.log(attributename+": "+myobject[attributename]);
}
myobject could be your json.data
myobject 可能是你的 json.data
回答by mak
You may also want to use hasOwnPropertyin the loop.
您可能还想在循环中使用hasOwnProperty。
for (var prop in obj) {
if (obj.hasOwnProperty(prop)) {
switch (prop) {
// obj[prop] has the value
}
}
}
node.js is single-threaded which means your script will block whether you want it or not. Remember that V8 (Google's Javascript engine that node.js uses) compiles Javascript into machine code which means that most basic operations are really fast and looping through an object with 100 keys would probably take a couple of nanoseconds?
node.js 是单线程的,这意味着无论您是否需要,您的脚本都会阻塞。还记得 V8(node.js 使用的谷歌 Javascript 引擎)将 Javascript 编译成机器码,这意味着大多数基本操作都非常快,循环遍历一个具有 100 个键的对象可能需要几纳秒?
However, if you do a lot more inside the loop and you don't want it to block right now, you could do something like this
但是,如果你做更多的内环路,你不希望它阻止现在,你可以做这样的事情
switch (prop) {
case 'Timestamp':
setTimeout(function() { ... }, 5);
break;
case 'Start_Value':
setTimeout(function() { ... }, 10);
break;
}
If your loop is doing some very CPU intensive work, you will need to spawn a child processto do that work or use web workers.
如果您的循环正在做一些非常占用 CPU 的工作,您将需要产生一个子进程来完成这项工作或使用web workers。
回答by Nathan Sweet
I would recommend taking advantage of the fact that nodeJS will always be ES5. Remember this isn't the browser folks you can depend on the language's implementation on being stable. That said I would recommend against ever using a for-in loop in nodeJS, unless you really want to do deep recursion up the prototype chain. For simple, traditional looping I would recommend making good use of Object.keys method, in ES5. If you view the following JSPerf test, especially if you use Chrome (since it has the same engine as nodeJS), you will get a rough idea of how much more performant using this method is than using a for-in loop (roughly 10 times faster). Here's a sample of the code:
我建议利用 nodeJS 将始终是 ES5 的事实。请记住,这不是您可以依赖语言实现稳定的浏览器人员。也就是说,我不建议在 nodeJS 中使用 for-in 循环,除非你真的想在原型链上进行深度递归。对于简单的传统循环,我建议在 ES5 中充分利用 Object.keys 方法。如果您查看以下JSPerf 测试,特别是如果您使用 Chrome(因为它具有与 nodeJS 相同的引擎),您将大致了解使用此方法比使用 for-in 循环(大约 10 倍)的性能高多少快点)。下面是代码示例:
var keys = Object.keys( obj );
for( var i = 0,length = keys.length; i < length; i++ ) {
obj[ keys[ i ] ];
}
回答by Mike Scott
If you want to avoid blocking, which is only necessary for very large loops, then wrap the contents of your loop in a function called like this: process.nextTick(function(){<contents of loop>}), which will defer execution until the next tick, giving an opportunity for pending calls from other asynchronous functions to be processed.
如果你想避免阻塞,这只是非常大的循环所必需的,然后将你的循环的内容包装在一个这样调用的函数中:process.nextTick(function(){<contents of loop>}),它将执行推迟到下一个滴答声,为来自其他异步函数的挂起调用提供机会待处理。
回答by Nish
If we are using nodeJS, we should definitely take advantage of different libraries it provides. Inbuilt functions like each(), map(), reduce() and many more from underscoreJS reduces our efforts. Here's a sample
如果我们使用 nodeJS,我们绝对应该利用它提供的不同库。像each()、map()、reduce()等来自underscoreJS的内置函数减少了我们的工作量。这是一个示例
var _=require("underscore");
var fs=require("fs");
var jsonObject=JSON.parse(fs.readFileSync('YourJson.json', 'utf8'));
_.map( jsonObject, function(content) {
_.map(content,function(data){
if(data.Timestamp)
console.log(data.Timestamp)
})
})
回答by Tharanga
My most preferred way is,
我最喜欢的方式是,
var objectKeysArray = Object.keys(yourJsonObj)
objectKeysArray.forEach(function(objKey) {
var objValue = yourJsonObj[objKey]
})
回答by JWally
Not sure if it helps, but it looks like there might be a library for async iteration in node hosted here:
https://github.com/caolan/async
不确定它是否有帮助,但看起来这里托管的节点中可能有一个异步迭代库:
https : //github.com/caolan/async
Async is a utility module which provides straight-forward, powerful functions for working with asynchronous JavaScript. Although originally designed for use with node.js, it can also be used directly in the browser.
Async provides around 20 functions that include the usual 'functional' suspects (map, reduce, filter, forEach…) as well as some common patterns for asynchronous control flow (parallel, series, waterfall…). All these functions assume you follow the node.js convention of providing a single callback as the last argument of your async function.
Async 是一个实用模块,它为使用异步 JavaScript 提供了直接、强大的功能。虽然最初是为与 node.js 一起使用而设计的,但它也可以直接在浏览器中使用。
Async 提供了大约 20 个函数,包括通常的“功能性”嫌疑(map、reduce、filter、forEach……)以及异步控制流的一些常见模式(并行、串行、瀑布……)。所有这些函数都假定您遵循 node.js 约定,即提供单个回调作为异步函数的最后一个参数。
回答by AlexGad
Take a look at Traverse. It will recursively walk an object tree for you and at every node you have a number of different objects you can access - key of current node, value of current node, parent of current node, full key path of current node, etc. https://github.com/substack/js-traverse. I've used it to good effect on objects that I wanted to scrub circular references to and when I need to do a deep clone while transforming various data bits. Here's some code pulled form their samples to give you a flavor of what it can do.
看看特拉弗斯。它将为您递归地遍历对象树,并且在每个节点上您都有许多可以访问的不同对象 - 当前节点的键、当前节点的值、当前节点的父节点、当前节点的完整键路径等。 https: //github.com/substack/js-traverse。我已经使用它对我想要清理循环引用的对象以及当我需要在转换各种数据位时进行深度克隆时取得了良好的效果。这是从他们的示例中提取的一些代码,让您了解它可以做什么。
var id = 54;
var callbacks = {};
var obj = { moo : function () {}, foo : [2,3,4, function () {}] };
var scrubbed = traverse(obj).map(function (x) {
if (typeof x === 'function') {
callbacks[id] = { id : id, f : x, path : this.path };
this.update('[Function]');
id++;
}
});
console.dir(scrubbed);
console.dir(callbacks);
回答by Asad Ali Choudhry
Its too late, But I believe some further clarification is required as below
为时已晚,但我认为需要进一步澄清如下
You can iterate through JSON Array with a simple loop as well, like
您也可以使用简单的循环遍历 JSON 数组,例如
for(var i = 0;i< jsonArray.length;i++)
{
console.log(jsonArray[i].attributename);
}
If you have a json object and you want to loop through all of its inner objects, Then you first need to get all the keys array and loop through the keys to retrieve objects with key names like
如果您有一个 json 对象并且您想遍历其所有内部对象,那么您首先需要获取所有键数组并遍历键以检索具有键名称的对象,例如
var keys = Object.keys(jsonObject);
for(var i=0,i < keys.length;i++)
{
var key = keys[i];
console.log(jsonObject.key.attributename);
}

