node.js의 개체 키를 반복합니다.
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
.
원하는 것은 개체 또는 어레이에 대한 느린 반복입니다.ES5에서는 이 작업이 불가능합니다(따라서 node.js에서는 불가능).우리는 결국 이것을 얻을 것입니다.
유일한 해결책은 V8을 확장하여 반복기(및 생성기)를 구현하는 노드 모듈을 찾는 것입니다.어떤 구현체도 찾을 수 없었습니다.당신은 거미원숭이 소스 코드를 보고 C++로 V8 확장자로 써볼 수 있습니다.
다음을 시도할 수 있지만 모든 키가 메모리에 로드됩니다.
Object.keys(o).forEach(function(key) {
var val = o[key];
logic();
});
하지만 그 이후로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);
});
또한 다음과 같이 사용할 객체를 지정하는 함수에 두 번째 인수를 전달할 수 있습니다.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);
키/값의 단순한 반복을 위해 때때로 언더스코어와 같은 라이브러리가 친구가 될 수 있습니다.
const _ = require('underscore');
_.each(a, function (value, key) {
// handle
});
참고로
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");
코드를 조정합니다.
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);
});
자신만의 반복기를 쉽게 작성할 수 있습니다.
let iterateObject = function*(obj) {
for (let k in obj) yield [ k, obj[k] ];
};
이제 할 수 있습니다.
let myObj = {
a: 1,
b: 2,
c: 3
};
for (let [ k, v ] of iterateObject(myObj)) {
console.log({ k, v });
}
// Produces:
// >> { k: 'a', v: 1 }
// >> { k: 'b', v: 2 }
// >> { k: 'c', v: 3 }
이 방법을 사용하면 모든 개체 값을 메모리에 저장할 수 없습니다!
프로토타입을 수정하는 것도 가능합니다(흔히 싫어하지만 환경을 충분히 제어하고 사용할 수 있는지 확인합니다).Object.defineProperty
와 함께{ enumerable: false }
단점은 거의 또는 전혀 없음):
// Add a Symbol.iterator property to Object.prototype
Object.defineProperty(Object.prototype, Symbol.iterator, {
enumerable: false,
value: function*() {
for (let k in this) yield [ k, this[k] ];
}
});
// Now we can iterate through any plain object
let obj = { a: 1, b: 2, c: 3, d: 4, e: 5 };
for (let [ k, v ] of obj) console.log([ k, v ]);
참고:function*(){}
노드 버전 이후 지원됨4.0.0
그리고 파괴 (에서 보듯이).for
제너레이터를 소비하는 루프)는 다음과 같이 지원됩니다.6.0.0
!
언급URL : https://stackoverflow.com/questions/7440001/iterate-over-object-keys-in-node-js
'sourcecode' 카테고리의 다른 글
Node.js AWS SDK에서 영역 구성 (0) | 2023.08.27 |
---|---|
Twitter 부트스트랩 버튼 텍스트 워드랩 (0) | 2023.08.27 |
Angular 4.3 HttpClient : 인터셉트 응답 (0) | 2023.08.27 |
R의 데이터 프레임에서 이미 존재하는 Excel 시트로 데이터를 추가하려면 어떻게 해야 합니까? (0) | 2023.08.27 |
구성 요소 Angular 2 내에서 리디렉션 (0) | 2023.08.27 |