我有一个需要迭代的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
}]
}
数据中的键并不总是相同的(我刚刚使用了示例,有20个不同的键),因此,我无法设置我的脚本以静态引用它们来获取值。
否则我可以陈述
var value1 = json.data.Timestamp;
var value2 = json.data.Start_Value;
var value3 = json.data.Abstract;
etc
过去我在数据节点上使用了一个简单的foreach循环...
foreach ($json->data as $key => $val) {
switch($key) {
case 'Timestamp':
//do this;
case: 'Start_Value':
//do this
}
}
但是不想阻止脚本。有什么想法吗?
答案 0 :(得分:77)
您可以通过以下方式迭代JavaScript对象:
for(var attributename in myobject){
console.log(attributename+": "+myobject[attributename]);
}
myobject可能是你的json.data
答案 1 :(得分:22)
您可能还想在循环中使用hasOwnProperty。
for (var prop in obj) {
if (obj.hasOwnProperty(prop)) {
switch (prop) {
// obj[prop] has the value
}
}
}
node.js是单线程的,这意味着您的脚本将阻止您是否需要它。请记住,V8(谷歌的node.js使用的Javascript引擎)将Javascript编译成机器代码,这意味着大多数基本操作都非常快,并且通过具有100个键的对象循环可能需要几纳秒的时间?
但是,如果你在循环中做了很多事情并且你不希望它现在阻止 ,你可以做这样的事情
switch (prop) {
case 'Timestamp':
setTimeout(function() { ... }, 5);
break;
case 'Start_Value':
setTimeout(function() { ... }, 10);
break;
}
如果您的循环正在进行一些CPU密集型工作,则需要生成child process来完成这项工作或使用web workers。
答案 2 :(得分:18)
我建议利用nodeJS永远是ES5的事实。请记住,这不是浏览器人可以依赖语言的稳定实现。这就是说我会建议不要在nodeJS中使用for-in循环,除非你真的想在原型链上进行深度递归。对于简单的传统循环,我建议在ES5中充分利用Object.keys方法。如果您查看以下JSPerf test,特别是如果您使用Chrome(因为它与nodeJS具有相同的引擎),您将大致了解使用此方法比使用for-in循环更多的性能(大约快10倍)。以下是代码示例:
var keys = Object.keys( obj );
for( var i = 0,length = keys.length; i < length; i++ ) {
obj[ keys[ i ] ];
}
答案 3 :(得分:6)
如果你想避免阻塞,这只是非常大的循环所必需的,那么将循环的内容包装在一个名为this process.nextTick(function(){<contents of loop>})
的函数中,这将把执行推迟到下一个tick,给出一个来自其他异步函数的待处理调用的处理机会。
答案 4 :(得分:3)
如果我们使用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)
})
})
答案 5 :(得分:2)
不确定它是否有帮助,但看起来在此处托管的节点中可能存在用于异步迭代的库:
https://github.com/caolan/async
< / p>
Async是一个实用程序模块,它提供了使用异步JavaScript的直接,强大的功能。虽然最初设计用于node.js,但它也可以直接在浏览器中使用。
Async提供了大约20个函数,包括通常的“功能”嫌疑(map,reduce,filter,forEach ......)以及异步控制流的一些常见模式(parallel,series,waterfall ...)。所有这些函数都假定您遵循node.js约定,即提供单个回调作为异步函数的最后一个参数。
答案 6 :(得分:1)
看看Traverse。它将递归地为您移动一个对象树,并且在每个节点上您都可以访问许多不同的对象 - 当前节点的键,当前节点的值,当前节点的父节点,当前节点的完整密钥路径等。{{ 3}}。我已经将它用于我想要擦除循环引用的对象,以及当我需要在转换各种数据位时进行深度克隆时。这里有一些代码从他们的样本中提取出来,让你了解它可以做些什么。
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);
答案 7 :(得分:1)
我最喜欢的方式是,
var objectKeysArray = Object.keys(yourJsonObj)
objectKeysArray.forEach(function(objKey) {
var objValue = yourJsonObj[objKey]
})
答案 8 :(得分:0)
为时已晚,但我认为需要进行如下进一步的澄清
您也可以通过一个简单的循环遍历JSON数组,例如
for(var i = 0;i< jsonArray.length;i++)
{
console.log(jsonArray[i].attributename);
}
如果您有一个json对象,并且想要遍历其所有内部对象,则首先需要获取所有keys数组并遍历这些键以检索具有键名之类的对象
var keys = Object.keys(jsonObject);
for(var i=0,i < keys.length;i++)
{
var key = keys[i];
console.log(jsonObject.key.attributename);
}