通过node.js循环使用JSON

时间:2011-04-29 07:08:10

标签: json asynchronous node.js foreach

我有一个需要迭代的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
    }
}

但是不想阻止脚本。有什么想法吗?

9 个答案:

答案 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);
}