node.js에서 객체 키를 반복


139

Javascript 1.7부터 Iterator 객체가 있습니다.

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

node.js에 이와 같은 것이 있습니까?

지금 나는 사용하고 있습니다 :

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

그러나 모든 객체 키를에 저장하여 많은 오버 헤드를 생성합니다 k.


당신은 이것을 본 적 있습니까? ejohn.org/blog/unimpressed-by-nodeiterator
jcolebrand

2
어떤 오버 헤드? 키와 이터레이터는 몇 개입니까? 그들의 제품이 백만 미만이라면,이 '비 효율성'을 무시하십시오.
c69

@jcolebrand φ : createNodeIteratorDOM 요소에 대한 것 같습니다 .DOM조차 없습니다.) @ c69 : keys객체의 모든 데이터를 저장하고 실제로 (700k 키에서 약 20MB)로 value설정되어 있습니다. 1이제 나는이 '오버 헤드'를 무시하고 있지만 더 나은 솔루션을 선호합니다 :)
stewe

나는 그것을 엉망으로 만드는 클래스로 보았다
jcolebrand

답변:


246

원하는 것은 객체 또는 배열에 대한 게으른 반복입니다. ES5에서는 불가능합니다 (따라서 node.js에서는 불가능합니다). 우리는 결국 이것을 얻을 것입니다.

유일한 해결책은 반복기 (및 아마도 발전기)를 구현하기 위해 V8을 확장하는 노드 모듈을 찾는 것입니다. 구현을 찾을 수 없습니다. spidermonkey 소스 코드를보고 C ++에서 V8 확장으로 작성해보십시오.

다음을 시도해 볼 수도 있지만 모든 키를 메모리에로드합니다.

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

그러나 Object.keys기본 방법이므로 더 나은 최적화가 가능할 수 있습니다.

기준

보시다시피 Object.keys가 훨씬 빠릅니다. 실제 메모리 스토리지가 더 최적인지 여부는 다른 문제입니다.

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

고마워!, 이것은 내 반복자를 약간 향상시킵니다 :) (코드 업데이트) 슬프게도 메모리 문제는 남아 있습니다 :( 그리고 forEach각 반복 단계가 비동기에서 호출되어야 하기 때문에 사용할 수 없습니다 setTimeout.
stewe

@stewe은 부가async.forEach
Raynos에게

명확하게 해 주셔서 감사합니다! 아마도 C ++ 확장 접근법을 시도 할 것입니다.
stewe

2
@stewe 글을 쓰려면 github에 게시하고 여기에 대한 답변이나 의견으로 링크를 남겨주십시오. o /
Raynos

그 C ++ 확장에 대해 @stewe, 작성 했습니까?
Raynos

22

또한 키워드 .forEach()로 사용할 객체를 지정 하는 두 번째 인수를 함수에 전달할 수 있습니다 this.

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

5
스레드에 대한 좋은 추가,하지만 ... 왜 지구상에서 객체의 키가 "element"라는 것으로 전달되고 "key"라는 키 배열의 열거자가 표시되는 이유는 무엇입니까?! 사용하도록 코드 샘플을 업데이트 할 수 있습니까?Object.keys(myObject).forEach(function(key, index, arrayOfKeys) {
Andy Lorenz

4

키 / 값의 간단한 반복을 위해 때로는 밑줄 과 같은 라이브러리가 친구가 될 수 있습니다.

const _ = require('underscore');

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

참고로


그것은 나를 위해 일했다. 에 대해 알고하지 마십시오 underscorejs. 이 기능을 lodash라이브러리 에서 사용했습니다 .
Neerali Acharya

3

나는 node.js를 처음 접했지만 (약 2 주), 객체의 내용을 콘솔에 재귀 적으로보고하는 모듈을 만들었습니다. 모든 항목을 나열하거나 특정 항목을 검색 한 다음 필요한 경우 지정된 깊이로 드릴 ​​다운합니다.

아마도 필요에 맞게이를 사용자 정의 할 수 있습니다. 단순하게 유지하십시오! 왜 복잡합니까? ...

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

0

그의 코드를 조정하십시오.

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);
    });
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.