Node.js এ অবজেক্ট কীগুলির উপরে আইট্রেট করুন


139

জাভাস্ক্রিপ্ট ১.7 থেকে একটি আইট্রেটার অবজেক্ট রয়েছে যা এটির অনুমতি দেয়:

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

নোড.জেএসএস এ কি এমন কিছু আছে?

এখনই আমি ব্যবহার করছি:

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
কি উপরি? আপনার কাছে কতগুলি কী এবং পুনরাবৃত্তি রয়েছে? যদি তাদের পণ্য 1 মিলিয়নেরও কম হয় তবে কেবল এই 'অদক্ষতা' উপেক্ষা করুন।
c69

@ জকোলেব্রান্ড φ: মনে createNodeIteratorহয় এটি ডোম উপাদানগুলির জন্য, আমার কাছে একটি ডিওএমও নেই;) @ c69: আমি সমস্ত ডেটা keysঅবজেক্টের মধ্যে সংরক্ষণ করি এবং এটি valueকেবলমাত্র 1(700k কীতে প্রায় 20MB) সেট করা আছে , প্রকৃতপক্ষে এখন আমি কেবল এই 'ওভারহেড' উপেক্ষা করছি, তবে আমি আরও ভাল সমাধান পছন্দ
করবো

আমি এটিকে ক্লাস হিসাবে দেখেছি যে ;-) এর সাথে
গোলমাল

উত্তর:


246

আপনি যা চান তা কোনও বস্তু বা অ্যারের উপরে অলস পুনরাবৃত্তি। ES5 এ এটি সম্ভব নয় (এভাবে নোড.জেএসে সম্ভব নয়)। আমরা শেষ পর্যন্ত এটি পেতে হবে।

একমাত্র সমাধানটি এমন একটি নোড মডিউল সন্ধান করছে যা পুনরাবৃত্তকারী (এবং সম্ভবত জেনারেটর) প্রয়োগ করতে V8 প্রসারিত করে। আমি কোনও প্রয়োগ খুঁজে পাইনি। আপনি স্পাইডারমনকি সোর্স কোডটি দেখতে এবং এটি 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);
});

! ধন্যবাদ, এই আমার পুনরুক্তিকারীর একটু :) (কোড আপডেট) কিন্তু দুঃখিতভাবে মেমরির ইস্যু দেহাবশেষ উন্নত :( এবং আমি ব্যবহার করতে পারবেন না forEachযেহেতু প্রতিটি পুনরাবৃত্তির পদক্ষেপ একটি ASYNC থেকে প্রার্থনা করা উচিত setTimeout
stewe

@ স্টেউ একটি যোগ করেছেনasync.forEach
রায়নস

সুস্পষ্ট করার জন্য ধন্যবাদ! আমি সম্ভবত সি ++ এক্সটেনশন পদ্ধতির চেষ্টা করব।
স্টিভ

2
@ যদি আপনি এটি লিখতে পরিচালনা করেন তবে এটি গিথুবে প্রকাশ করুন এবং একটি উত্তরের উত্তর বা একটি মন্তব্যে এটির একটি লিঙ্ক ছেড়ে যান /
রায়নস

@ যে সি ++ এক্সটেনশান সম্পর্কে সত্য, আপনি কি এটি লেখেন?
রায়নস

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
থ্রেডের সাথে যুক্ত হ'ল, তবে ... কেন পৃথিবীতে অবজেক্টের কীটি "এলিমেন্ট" নামক কিছু হিসাবে পাস হচ্ছে এবং কীগুলি অ্যারের জন্য "কী" বলে? আমি কি আপনার কোড নমুনাটি ব্যবহার করতে আপডেট করতে পরামর্শ দেবObject.keys(myObject).forEach(function(key, index, arrayOfKeys) {
অ্যান্ডি লরেঞ্জ

4

কী / মানগুলির সাধারণ পুনরাবৃত্তির জন্য, কখনও কখনও আন্ডারস্কোর মতো লাইব্রেরি আপনার বন্ধু হতে পারে।

const _ = require('underscore');

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

শুধু রেফারেন্সের জন্য


এটা আমার জন্য কাজ করেছে। সম্পর্কে জানেন না underscorejs। আমি lodashলাইব্রেরি থেকে এই ফাংশন ব্যবহার করেছি ।
নেরালালি আচার্য

3

আমি নোড.জেএসে (প্রায় 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.