159 votes

Itération sur les clés des objets en node.js

Depuis Javascript 1.7, il existe un Itérateur qui permet cela :

var a={a:1,b:2,c:3};
var it=Iterator(a);

function iterate(){
    try {  
        console.log(it.next());
        setTimeout(iterate,1000);
    }catch (err if err instanceof StopIteration) {  
        console.log("End of record.\n");  
    } catch (err) {  
        console.log("Unknown error: " + err.description + "\n");  
    }  

}
iterate();

Existe-t-il quelque chose comme ça dans node.js ?

En ce moment, j'utilise :

function Iterator(o){
    /*var k=[];
    for(var i in o){
        k.push(i);
    }*/
    var k=Object.keys(o);
    return {
        next:function(){
            return k.shift();
        }
    };
}

mais cela produit beaucoup de surcharge en stockant toutes les clés de l'objet dans k .

267voto

Raynos Points 82706

Ce que vous voulez, c'est une itération paresseuse sur un objet ou un tableau. Ceci n'est pas possible dans ES5 (donc pas possible dans node.js). Nous y arriverons un jour.

La seule solution est de trouver un module de nœud qui étend V8 pour implémenter les itérateurs (et probablement les générateurs). Je n'ai pas trouvé d'implémentation. Vous pouvez regarder le code source de spidermonkey et essayer de l'écrire en C++ comme une extension V8.

Vous pouvez essayer ce qui suit, mais cela chargera également toutes les clés en mémoire.

Object.keys(o).forEach(function(key) {
  var val = o[key];
  logic();
});

Toutefois, étant donné que Object.keys est une méthode native, elle peut permettre une meilleure optimisation.

Point de repère

Comme vous pouvez le constater, Object.keys est nettement plus rapide. Que le stockage en mémoire soit plus optimal est une autre question.

var async = {};
async.forEach = function(o, cb) {
  var counter = 0,
    keys = Object.keys(o),
    len = keys.length;
  var next = function() {
    if (counter < len) cb(o[keys[counter++]], next);
  };
  next();
};

async.forEach(obj, function(val, next) {
  // do things
  setTimeout(next, 100);
});

26voto

amateur barista Points 1449

N'oubliez pas non plus que vous pouvez passer un deuxième argument à la fonction .forEach() en spécifiant l'objet à utiliser comme this mot-clé.

// myOjbect is the object you want to iterate.
// Notice the second argument (secondArg) we passed to .forEach.
Object.keys(myObject).forEach(function(element, key, _array) {
  // element is the name of the key.
  // key is just a numerical value for the array
  // _array is the array of all the keys

  // this keyword = secondArg
  this.foo;
  this.bar();
}, secondArg);

5voto

High6 Points 2434

Pour une simple itération de clés/valeurs, il arrive que des bibliothèques telles que underscorejs peut être votre ami.

const _ = require('underscore');

_.each(a, function (value, key) {
    // handle
});

à titre d'information

3voto

Je suis nouveau sur node.js (environ 2 semaines), mais je viens de créer un module qui rapporte récursivement à la console le contenu d'un objet. Il peut lister tous les éléments ou rechercher un élément spécifique, puis effectuer un forage d'une profondeur donnée si nécessaire.

Vous pouvez peut-être l'adapter à vos besoins. Restez simple ! Pourquoi compliquer ?...

'use strict';

//console.log("START: AFutils");

// Recusive console output report of an Object
// Use this as AFutils.reportObject(req, "", 1, 3); // To list all items in req object by 3 levels
// Use this as AFutils.reportObject(req, "headers", 1, 10); // To find "headers" item and then list by 10 levels
// yes, I'm OLD School!  I like to see the scope start AND end!!!  :-P
exports.reportObject = function(obj, key, level, deep) 
{
    if (!obj)
    { 
        return;
    }

    var nextLevel = level + 1;

    var keys, typer, prop;
    if(key != "")
    {   // requested field
        keys = key.split(']').join('').split('[');
    }
    else
    {   // do for all
        keys = Object.keys(obj);
    }
    var len = keys.length;
    var add = "";
    for(var j = 1; j < level; j++)
    {
        // I would normally do {add = add.substr(0, level)} of a precreated multi-tab [add] string here, but Sublime keeps replacing with spaces, even with the ["translate_tabs_to_spaces": false] setting!!! (angry)
        add += "\t";
    }

    for (var i = 0; i < len; i++) 
    {
        prop = obj[keys[i]];
        if(!prop)
        {
            // Don't show / waste of space in console window...
            //console.log(add + level + ": UNDEFINED [" + keys[i] + "]");
        }
        else
        {
            typer = typeof(prop);
            if(typer == "function")
            {
                // Don't bother showing fundtion code...
                console.log(add + level + ": [" + keys[i] + "] = {" + typer + "}");
            }
            else
            if(typer == "object")
            {
                console.log(add + level + ": [" + keys[i] + "] = {" + typer + "}");
                if(nextLevel <= deep)
                {
                    // drop the key search mechanism if first level item has been found...
                    this.reportObject(prop, "", nextLevel, deep); // Recurse into
                }
            }
            else
            {
                // Basic report
                console.log(add + level + ": [" + keys[i] + "] = {" + typer + "} = " + prop + ".");
            }
        }
    }
    return ;
};

//console.log("END: AFutils");

0voto

Lindy Points 54

Ajuster son code :

Object.prototype.each = function(iterateFunc) {
        var counter = 0,
keys = Object.keys(this),
currentKey,
len = keys.length;
        var that = this;
        var next = function() {

            if (counter < len) {
                currentKey = keys[counter++];
                iterateFunc(currentKey, that[currentKey]);

                next();
            } else {
                that = counter = keys = currentKey = len = next = undefined;
            }
        };
        next();
    };

    ({ property1: 'sdsfs', property2: 'chat' }).each(function(key, val) {
        // do things
        console.log(key);
    });

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X