webentwicklung-frage-antwort-db.com.de

Objektschlüssel in node.js durchlaufen

Seit Javascript 1.7 gibt es ein Iterator Objekt, das dies erlaubt:

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();

gibt es so etwas in node.js?

Im Moment verwende ich:

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

dies führt jedoch zu einem erheblichen Aufwand, da alle Objektschlüssel in k gespeichert werden.

120
stewe

Was Sie wollen, ist eine langsame Iteration über ein Objekt oder ein Array. Dies ist in ES5 nicht möglich (daher nicht in node.js möglich). Wir werden das irgendwann bekommen.

Die einzige Lösung besteht darin, ein Knotenmodul zu finden, das V8 erweitert, um Iteratoren (und wahrscheinlich Generatoren) zu implementieren. Ich konnte keine Implementierung finden. Sie können sich den Quellcode von Spidermonkey ansehen und versuchen, ihn in C++ als V8-Erweiterung zu schreiben.

Sie können Folgendes versuchen, es werden jedoch auch alle Schlüssel in den Speicher geladen

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

Da Object.keys jedoch eine native Methode ist, kann dies eine bessere Optimierung ermöglichen.

Benchmark

Wie Sie sehen können, ist Object.keys deutlich schneller. Ob der tatsächliche Speicherplatz optimaler ist, ist eine andere Sache.

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);
});
214
Raynos

Denken Sie auch daran, dass Sie ein zweites Argument an die Funktion .forEach() übergeben können, indem Sie das Objekt angeben, das als Schlüsselwort this verwendet werden soll.

// 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);
21
amateur barista

Ich bin zu node.js neu (ungefähr 2 Wochen), aber ich habe gerade ein Modul erstellt, das den Inhalt eines Objekts rekursiv an die Konsole meldet. Es listet alle auf oder sucht nach einem bestimmten Objekt und kann dann bei Bedarf eine bestimmte Tiefe anzeigen.

Vielleicht können Sie dies an Ihre Bedürfnisse anpassen. Halte es einfach! Warum komplizieren? ...

'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");

Für die einfache Wiederholung von Schlüsseln/Werten können manchmal Bibliotheken wie underscorejs Ihr Freund sein.

const _ = require('underscore');

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

nur als Referenz

1
H6.

seinen Code anpassen:

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);
    });
0
Lindy