web-dev-qa-db-fra.com

Boucle dans JSON avec node.js

J'ai un fichier JSON sur lequel j'ai besoin de parcourir, comme indiqué ci-dessous ...

{
    "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
    }]
}

Les clés dans les données ne seront pas toujours les mêmes (je viens d'utiliser des exemples, il y a 20 clés différentes) et, en tant que tel, je ne peux pas configurer mon script pour les référencer statiquement afin d'obtenir les valeurs.

Sinon, je pourrais dire

var value1 = json.data.Timestamp;
var value2 = json.data.Start_Value;
var value3 = json.data.Abstract;
etc

Dans le passé, j'ai utilisé une simple boucle foreach sur le nœud de données ...

foreach ($json->data as $key => $val) {
    switch($key) {
        case 'Timestamp':
            //do this;
        case: 'Start_Value':
            //do this
    }
}

Mais vous ne voulez pas bloquer le script. Des idées?

47
crawf

Vous pouvez parcourir les objets JavaScript de cette façon:

for(var attributename in myobject){
    console.log(attributename+": "+myobject[attributename]);
}

myobject pourrait être votre json.data

79
Van Coding

Vous pouvez aussi utiliser hasOwnProperty dans la boucle.

for (var prop in obj) {
    if (obj.hasOwnProperty(prop)) {
        switch (prop) {
            // obj[prop] has the value
        }
    }
}

node.js est mono-threaded, ce qui signifie que votre script bloquera que vous le vouliez ou non. Rappelez-vous que la V8 (le moteur Javascript de Google utilisé par node.js) compile Javascript en code machine, ce qui signifie que la plupart des opérations de base sont très rapides et que boucler un objet avec 100 clés prendrait probablement quelques nanosecondes?

Cependant, si vous faites beaucoup plus dans la boucle et que vous ne voulez pas qu'elle bloque maintenant , vous pourriez faire quelque chose comme ceci.

switch (prop) {
    case 'Timestamp':
        setTimeout(function() { ... }, 5);
        break;
    case 'Start_Value':
        setTimeout(function() { ... }, 10);
        break;
}

Si votre boucle effectue un travail très gourmand en ressources processeur, vous devrez générer un processus enfant pour effectuer ce travail ou utiliser travailleurs Web .

22
mak

Je recommanderais de tirer parti du fait que nodeJS sera toujours ES5. N'oubliez pas que ce ne sont pas les navigateurs que vous pouvez compter sur la stabilité de l'implémentation du langage. Cela dit, je vous déconseille d'utiliser une boucle for-in dans nodeJS, à moins que vous ne souhaitiez vraiment effectuer une récursion profonde dans la chaîne du prototype. Pour des boucles simples et traditionnelles, je vous recommanderais de bien utiliser la méthode Object.keys, dans ES5. Si vous affichez ce qui suit test JSPerf , en particulier si vous utilisez Chrome (puisqu'il a le même moteur que nodeJS), vous aurez une idée approximative de la quantité Cette méthode est plus performante que l’utilisation d’une boucle for-in (environ 10 fois plus rapide). Voici un exemple du code:

 var keys = Object.keys( obj );
 for( var i = 0,length = keys.length; i < length; i++ ) {
     obj[ keys[ i ] ];
 }
18
Nathan Sweet

Si vous voulez éviter le blocage, qui n'est nécessaire que pour les très grandes boucles, encapsulez le contenu de votre boucle dans une fonction appelée comme ceci: process.nextTick(function(){<contents of loop>}), qui retardera l'exécution jusqu'au prochain tick, ce qui donnera l'occasion pour les appels en attente d'autres fonctions asynchrones à traiter.

6
Mike Scott

Si nous utilisons nodeJS, nous devons absolument tirer parti des différentes bibliothèques qu’il fournit. Des fonctions incorporées telles que each (), map (), reduction () et beaucoup d’autres de underscoreJS réduisent nos efforts. Voici un échantillon

    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)          
           })
      })
3
Nish

Je ne suis pas sûr que cela aide, mais il semble y avoir une bibliothèque pour l'itération asynchrone dans le noeud hébergé ici:

https://github.com/caolan/async

Async est un module utilitaire qui fournit des fonctions simples et puissantes pour travailler avec JavaScript asynchrone. Bien que conçu à l'origine pour être utilisé avec node.js, il peut également être utilisé directement dans le navigateur.

Async fournit une vingtaine de fonctions, dont les suspects "fonctionnels" habituels (carte, réduire, filtrer, forEach…), ainsi que des modèles courants de flux de contrôle asynchrone (parallèle, série, cascade…). Toutes ces fonctions supposent que vous respectiez la convention de node.js qui consiste à fournir un seul rappel comme dernier argument de votre fonction async.

2
JWally

Jetez un coup d'œil à Traverse. Il parcourt récursivement une arborescence d'objets pour vous et vous avez accès à plusieurs objets différents pour chaque nœud - clé du nœud actuel, valeur du nœud actuel, parent du nœud actuel, chemin d'accès complet à la clé du nœud actuel, etc. - https://github.com/substack/js-traverse . Je l'ai utilisé à bon escient sur des objets pour lesquels je voulais effacer des références circulaires et lorsque je dois effectuer un clone en profondeur tout en transformant divers bits de données. Voici quelques exemples de code extraits de leurs échantillons pour vous donner une idée de ce qu’il peut faire.

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);
1
AlexGad

Ma façon préférée est

var objectKeysArray = Object.keys(yourJsonObj)
objectKeysArray.forEach(function(objKey) {
    var objValue = yourJsonObj[objKey]
})
1
Tharanga

C'est trop tard, mais je crois que des éclaircissements supplémentaires sont nécessaires comme ci-dessous

Vous pouvez parcourir le tableau JSON avec une simple boucle, comme

for(var i = 0;i< jsonArray.length;i++)
{
    console.log(jsonArray[i].attributename);
}

Si vous avez un objet JSON et que vous souhaitez parcourir tous ses objets internes, vous devez d'abord obtenir tous les tableaux de clés et parcourir les clés pour récupérer des objets avec des noms de clé tels que

var keys = Object.keys(jsonObject);
for(var i=0,i < keys.length;i++) 
{
    var key = keys[i];
    console.log(jsonObject.key.attributename);
}
0
Asad Ali Choudhry