javascript - atscript - स्क्रिप्टिंग भाषा




जावास्क्रिप्ट में किसी ऑब्जेक्ट की कुंजी/गुणों की कुशलतापूर्वक गणना कैसे करें? (12)

Google क्लोजर के लिए यह एक अच्छा काम है ... goog.object.getCount (obj)

goog.Object दस्तावेज़ीकरण पर देखो

ऑब्जेक्ट की कुंजियों / गुणों की संख्या को गिनने का सबसे तेज़ तरीका क्या है? ऑब्जेक्ट पर पुन: प्रयास किए बिना ऐसा करना संभव है? यानी बिना किए

var count = 0;
for (k in myobj) if (myobj.hasOwnProperty(k)) count++;

(फ़ायरफ़ॉक्स ने एक जादू __count__ संपत्ति प्रदान की थी, लेकिन इसे संस्करण 4 के आसपास कहीं हटा दिया गया था)


आप इस कोड का उपयोग कर सकते हैं:

if (!Object.keys) {
    Object.keys = function (obj) {
        var keys = [],
            k;
        for (k in obj) {
            if (Object.prototype.hasOwnProperty.call(obj, k)) {
                keys.push(k);
            }
        }
        return keys;
    };
}

फिर आप इसे पुराने ब्राउज़र में भी उपयोग कर सकते हैं:

var len = Object.keys(obj).length;

उन लोगों के लिए जिनके पास अंडरस्कोर.जेएस शामिल हैं, वे आपके प्रोजेक्ट में शामिल कर सकते हैं:

_({a:'', b:''}).size() // => 2

या कार्यात्मक शैली:

_.size({a:'', b:''}) // => 2

उन लोगों के लिए जिनके पास अपनी परियोजना में एक्सटी जेएस 4 है, आप कर सकते हैं:

Ext.Object.getSize(myobj);

इसका लाभ यह है कि यह सभी एक्स संगत ब्राउज़रों (आईई 6-आईई 8 शामिल) पर काम करेगा, हालांकि, मेरा मानना ​​है कि चलने का समय ओ (एन) से बेहतर नहीं है, हालांकि अन्य सुझाए गए समाधानों के साथ।


किसी भी ईएस 5-संगत वातावरण में ऐसा करने के लिए, जैसे नोड , क्रोम, आईई 9 +, एफएफ 4+, या सफारी 5+:

Object.keys(obj).length

जैसा कि ऊपर उत्तर दिया गया है: Object.keys(obj).length

लेकिन: जैसा कि अब हमारे पास ES6 में एक वास्तविक Map वर्ग है, मैं किसी ऑब्जेक्ट के गुणों का उपयोग करने के बजाय इसका उपयोग करने का suggest दूंगा।

const map = new Map();
map.set("key", "value");
map.size; // THE fastest way

प्रेषक: https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty

ऑब्जेक्ट.डेफिनप्रोपर्टी (ओबीजे, प्रोप, डिस्क्रिप्टर)

आप इसे अपने सभी ऑब्जेक्ट्स में जोड़ सकते हैं:

Object.defineProperty(Object.prototype, "length", {
    enumerable: false,
    get: function() {
        return Object.keys(this).length;
    }
});

या एक वस्तु:

var myObj = {};
Object.defineProperty(myObj, "length", {
    enumerable: false,
    get: function() {
        return Object.keys(this).length;
    }
});

उदाहरण:

var myObj = {};
myObj.name  = "John Doe";
myObj.email = "[email protected]";
myObj.length; //output: 2

उस तरह से जोड़ा गया, यह for..in loops में प्रदर्शित नहीं किया जाएगा:

for(var i in myObj) {
     console.log(i + ":" + myObj[i]);
}

आउटपुट:

name:John Doe
email:[email protected]

नोट: यह <IE9 ब्राउज़र में काम नहीं करता है।


मानक ऑब्जेक्ट कार्यान्वयन ( ES5.1 ऑब्जेक्ट आंतरिक गुणों और विधियों ) को किसी कुंजी को अपने कुंजी / गुणों को ट्रैक करने के लिए किसी Object आवश्यकता नहीं होती है, इसलिए किसी Object के आकार को स्पष्ट रूप से या स्पष्ट रूप से इसके कुंजियों पर फिर से चलाने के बिना कोई मानक तरीका नहीं होना चाहिए ।

तो यहां सबसे अधिक उपयोग किए जाने वाले विकल्प हैं:

1. ईसीएमएस्क्रिप्ट की ऑब्जेक्ट.की ()

Object.keys(obj).length; अस्थायी सरणी की गणना करने और इसकी लंबाई लौटने के लिए आंतरिक रूप से चाबियों पर फिर से चलने से काम करता है।

  • पेशेवर - पठनीय और साफ वाक्यविन्यास। मूल समर्थन अनुपलब्ध होने पर शिम को छोड़कर कोई लाइब्रेरी या कस्टम कोड आवश्यक नहीं है
  • विपक्ष - सरणी के निर्माण के कारण मेमोरी ओवरहेड।

2. पुस्तकालय आधारित समाधान

इस विषय में कहीं और पुस्तकालय-आधारित उदाहरण उनकी लाइब्रेरी के संदर्भ में उपयोगी मुहावरे हैं। एक प्रदर्शन दृष्टिकोण से, हालांकि, एक पूर्ण नो-लाइब्रेरी कोड की तुलना में लाभ प्राप्त करने के लिए कुछ भी नहीं है क्योंकि उन सभी लाइब्रेरी विधियों में वास्तव में फॉर-लूप या Object.keys (मूल या shimmed) को समाहित किया जाता है।

3. फॉर-लूप अनुकूलित करना

फ़ंक्शन कॉल ओवरहेड की वजह से इस तरह के फॉर-लूप का सबसे धीमा हिस्सा आमतौर पर .hasOwnProperty() कॉल होता है। तो जब मैं सिर्फ एक JSON ऑब्जेक्ट की प्रविष्टियों की संख्या चाहता हूं, तो मैं बस .hasOwnProperty() कॉल को छोड़ देता .hasOwnProperty() अगर मुझे पता है कि कोई कोड नहीं हुआ है और न ही Object.prototype विस्तार Object.prototype

अन्यथा, आपके कोड को स्थानीय ( var k ) बनाकर और पोस्टफिक्स के बजाय उपसर्ग-वृद्धि ऑपरेटर ( ++count ) का उपयोग करके अनुकूलित किया जा सकता है।

var count = 0;
for (var k in myobj) if (myobj.hasOwnProperty(k)) ++count;

एक और विचार hasOwnProperty विधि को कैशिंग करने पर निर्भर करता है:

var hasOwn = Object.prototype.hasOwnProperty;
var count = 0;
for (var k in myobj) if (hasOwn.call(myobj, k)) ++count;

चाहे यह किसी भी पर्यावरण पर तेज़ है या नहीं, बेंचमार्किंग का सवाल है। वैसे भी बहुत सीमित प्रदर्शन लाभ की उम्मीद की जा सकती है।


मुझे नहीं लगता कि यह संभव है (कम से कम कुछ आंतरिक उपयोग किए बिना नहीं)। और मुझे नहीं लगता कि आपको इसे अनुकूलित करके बहुत कुछ हासिल होगा।


मैं इसे इस तरह की सभी वस्तुओं के लिए उपलब्ध कराने की कोशिश करता हूं:

Object.defineProperty(Object.prototype, "length", {
get() {
    if (!Object.keys) {
        Object.keys = function (obj) {
            var keys = [],k;
            for (k in obj) {
                if (Object.prototype.hasOwnProperty.call(obj, k)) {
                    keys.push(k);
                }
            }
            return keys;
        };
    }
    return Object.keys(this).length;
},});

console.log({"Name":"Joe","Age":26}.length) //returns 2

यदि आप Underscore.js का उपयोग कर रहे हैं तो आप _.size (धन्यवाद @douwe) का उपयोग कर सकते हैं:
_.size(obj)

वैकल्पिक रूप से आप _.keys भी उपयोग कर सकते हैं जो कुछ के लिए स्पष्ट हो सकता है:
_.keys(obj).length

मैं अत्यधिक अंडरस्कोर की सिफारिश करता हूं, यह बहुत सी बुनियादी चीजें करने के लिए एक तंग लाइब्रेरी है। जब भी संभव हो वे ईसीएमए 5 से मेल खाते हैं और मूल कार्यान्वयन के लिए स्थगित होते हैं।

अन्यथा मैं @ एवी के जवाब का समर्थन करता हूं। मैंने इसे एमडीसी दस्तावेज़ में एक लिंक जोड़ने के लिए संपादित किया जिसमें कुंजी () विधि शामिल है जिसे आप गैर-ईसीएमए 5 ब्राउज़र में जोड़ सकते हैं।


यदि आप वास्तव में एक प्रदर्शन समस्या में चल रहे हैं तो मैं उन कॉलों को लपेटने का सुझाव दूंगा जो ऑब्जेक्ट से / से किसी फ़ंक्शन के साथ गुणों को जोड़ / हटाते हैं जो एक उचित नाम (आकार?) संपत्ति में वृद्धि / कमी भी करता है।

आपको केवल एक बार गुणों की प्रारंभिक संख्या की गणना करने और वहां से आगे बढ़ने की आवश्यकता है। यदि कोई वास्तविक प्रदर्शन समस्या नहीं है, तो परेशान न करें। फ़ंक्शन में कोड के उस बिट को बस लपेटें getNumberOfProperties(object) और इसके साथ किया जाए।






key