जावास्क्रिप्ट में सरणी कुंजियाँ कैसे प्राप्त करें?


80

मेरे पास इस कोड के साथ बनाई गई एक सरणी है:

var widthRange = new Array();
widthRange[46] = { min:0,  max:52 };
widthRange[66] = { min:52, max:70 };
widthRange[90] = { min:70, max:94 };

मैं एक लूप में 46, 66, 90 में से प्रत्येक मान प्राप्त करना चाहता हूं। मैंने कोशिश की, for (var key in widthRange)लेकिन इससे मुझे अतिरिक्त गुणों का एक पूरा गुच्छा मिल गया (मुझे लगता है कि वे ऑब्जेक्ट पर कार्य कर रहे हैं)। मैं लूप के लिए एक नियमित उपयोग नहीं कर सकता क्योंकि मान अनुक्रमिक नहीं हैं।


9
ऐसा लगता है कि आपके पास डेटा है, जबकि यह संख्यात्मक कुंजियों के लिए होता है, वास्तव में सरणी डेटा नहीं है। मैं यहाँ एक नियमित वस्तु का उपयोग कर रहा हूँ।
क्वेंटिन

@ क्वेंटिन इसे विरल सरणी कहा जाता है। प्रदर्शन-वार, यहां किसी ऑब्जेक्ट के बजाय एक सरणी का उपयोग करना सबसे अच्छा है। इसके अलावा, प्रदर्शन-वार, सबसे अच्छा उत्तर भी सूचीबद्ध नहीं है Array.prototype.forEach:। Object.keysकिसी सरणी पर कॉल करना असाध्य है क्योंकि ब्राउज़र इसके लिए अनुकूलन नहीं करते हैं। for(var key in array)यह बुरा है क्योंकि यह प्रोटोटाइप को ट्रेस करता है और प्रत्येक नंबर कुंजी को जोड़ता है जो इसका सामना करता है (डबल्स को बेस 10 में परिवर्तित करना बहुत धीमा है)। forEach, हालांकि, विरल सरणियों को पुनरावृत्त करने के उद्देश्य के लिए बिल्कुल तैयार किया गया था और अन्य समाधानों की तुलना में आपके कोड को उत्कृष्ट प्रदर्शन देगा
जैक गिफिन

जवाबों:


96

आपको कॉल करने की आवश्यकता है hasOwnProperty यह देखने के फ़ंक्शन कि क्या संपत्ति वास्तव में ऑब्जेक्ट पर ही परिभाषित है (जैसा कि इसके प्रोटोटाइप के विपरीत), इस तरह:

for (var key in widthRange) {
    if (key === 'length' || !widthRange.hasOwnProperty(key)) continue;
    var value = widthRange[key];
}

ध्यान दें कि आपको एक अलग चेक की आवश्यकता है length
हालाँकि, आपको यहाँ किसी सरणी का उपयोग नहीं करना चाहिए; आपको एक नियमित वस्तु का उपयोग करना चाहिए। सभी जावास्क्रिप्ट ऑब्जेक्ट्स सहयोगी सरणियों के रूप में कार्य करते हैं।

उदाहरण के लिए:

var widthRange = { };  //Or new Object()
widthRange[46] = { sel:46, min:0,  max:52 };
widthRange[66] = { sel:66, min:52, max:70 };
widthRange[90] = { sel:90, min:70, max:94 };

2
वास्तव में? वाह, मैं यहां हर दिन कुछ सीखता हूं, और इसलिए यह अक्सर आपसे होता है। :-) मैं हैरान हूं कि एरे अपने स्पष्ट रूप से सेट किए गए अनुक्रमों का ट्रैक रखता है। शायद मुझे नहीं होना चाहिए
पॉंच

@ एसएलएसी: धन्यवाद, इसे किसी वस्तु में बदलना सबसे अच्छा समाधान लगता है। एक और प्रश्न: क्या रिवर्स ऑर्डर में पुनरावृति करने का एक तरीका है?
असंतुष्टगीतगो

नहीं; आपको इसे स्वयं करने की आवश्यकता होगी।
SLaks

2
आपको अलग से जांच की आवश्यकता क्यों है length? क्या [[DontEnum]]सभी ब्राउज़रों में चिह्नित नहीं किया गया है ?
रोहिन मार्थ

@Roatin: मुझे नहीं पता। माफी से अधिक सुरक्षित।
एसएलके

84

कड़े कीज़ के साथ पूछताछ की जा सकती है Object.keys(array)


4
यह कुंजी को स्ट्रिंग्स के रूप में लौटाता है, संख्याओं को नहीं, बस हर कोई जानता है।
हच मूर

सबसे अच्छा समाधान ... TY
कार्लोस गेलियानो

मेरा दिन बना दिया! : D <3 इसे हल कर दिया जहां array.keys()कुछ भी नहीं लौटाया।
क्रिस्टोफर स्टॉक

18

यदि आप किसी भी प्रकार की सरणी / संग्रह हेरफेर कर रहे हैं या निरीक्षण कर रहे हैं तो मैं अंडरस्कोर.जे का उपयोग करने की अत्यधिक अनुशंसा करता हूं । यह छोटा है, अच्छी तरह से परीक्षण किया गया है और आपको जावास्क्रिप्ट सिरदर्द के दिनों / हफ्तों / वर्षों से बचाएगा। यहाँ इसकी कुंजी समारोह है:

चांबियाँ

ऑब्जेक्ट के गुणों के सभी नामों को पुनः प्राप्त करें।

_.keys({one : 1, two : 2, three : 3});
=> ["one", "two", "three"]

4

कहो कि आपकी सरणी आपकी arr = [ { a: 1, b: 2, c: 3 }, { a: 4, b: 5, c: 6 }, { a: 7, b: 8, c: 9 } ](या संभवतः अन्य कुंजियों की तरह) दिखती है, जो आप कर सकते हैं

arr.map((o) => {
    return Object.keys(o)
}).reduce((prev, curr) => {
    return prev.concat(curr)
}).filter((col, i, array) => {
    return array.indexOf(col) === i
});

["a", "b", "c"]


3
for (var i = 0; i < widthRange.length; ++i) {
  if (widthRange[i] != null) {
    // do something
  }
}

आप वास्तव में आपके द्वारा सेट की गई कुंजियों को प्राप्त नहीं कर सकते हैं क्योंकि यह नहीं है कि कैसे एक ऐरे काम करता है। एक बार जब आप तत्व 46 सेट करते हैं, तो आपके पास 45 सेट के माध्यम से 0 भी होता है (हालांकि वे शून्य हैं)।

आपके पास हमेशा दो सरणियाँ हो सकती हैं :

var widthRange = [], widths = [], newVal = function(n) {
  widths.push(n);
  return n;
};
widthRange[newVal(26)] = { whatever: "hello there" };

for (var i = 0; i < widths.length; ++i) {
  doSomething(widthRange[widths[i]]);
}

अच्छी तरह से संपादित करें यह हो सकता है कि मैं यहाँ सब गीला हूँ ...


Arrays केवल लंबाई का ट्रैक रखती है, वे कई वस्तुओं के माध्यम से नहीं जाते हैं और बनाते हैं। मूल रूप से, जब एक नया सूचकांक पाया जाता है, तो यह देखने के लिए जांच करता है कि क्या नया सूचकांक लंबाई से अधिक है ... यदि यह है कि नया सूचकांक नई लंबाई बन जाता है। इस वजह से यह संभव है कि आप केवल उन इंडेक्सों को प्राप्त करें जिनके लिए आपने लूप में परिभाषित किया है
बॉब


1

आपका मूल उदाहरण मेरे लिए ठीक काम करता है:

<html>
<head>
</head>
<body>
<script>
var widthRange = new Array();
widthRange[46] = { sel:46, min:0,  max:52 };
widthRange[66] = { sel:66, min:52, max:70 };
widthRange[90] = { sel:90, min:70, max:94 };

var i = 1;
for (var key in widthRange)
{
    document.write("Key #" + i + " = " + key + "; &nbsp;&nbsp;&nbsp; min/max = " + widthRange[key].min + "/" + widthRange[key].max + "<br />");
    i++;
}
</script>
</html>

ब्राउज़र में परिणाम (Windows XP पर फ़ायरफ़ॉक्स 3.6.2):

Key #1 = 46;     min/max = 0/52
Key #2 = 66;     min/max = 52/70
Key #3 = 90;     min/max = 70/94

2
मुझे यकीन है कि वह प्रोटोटाइप या ऐसा कुछ आयात कर रहा है। सामान्य तौर पर, "में" छोरों जोखिम भरा होता है।
पॉनीटी

वैसे मैं jQuery का उपयोग कर रहा हूँ, लेकिन Joomla जो mootools का उपयोग करता है, कुछ उन गुणों को जोड़ रहा है।
असंतुष्टगीत

1

मुझे लगता है कि आपको इसके लिए एक ऑब्जेक्ट ( {}) और एक सरणी ( []) का उपयोग नहीं करना चाहिए ।

डेटा का एक सेट प्रत्येक कुंजी के साथ जुड़ा हुआ है। यह एक वस्तु का उपयोग करने के लिए चिल्लाती है। कर:

var obj = {};
obj[46] = { sel:46, min:0,  max:52 };
obj[666] = { whatever:true };

// This is what for..in is for
for (var prop in obj) {
  console.log(obj[prop]);
}

शायद इस तरह कुछ उपयोगिता सामान मदद कर सकते हैं:

window.WidthRange = (function () {
  var obj = {};
  return {
    getObj: function () {return obj;}
    , add: function (key, data) {
        obj[key] = data;
        return this; // enabling chaining
      }
  }
})();

// Usage (using chaining calls):
WidthRange.add(66, {foo: true})
.add(67, {bar: false})
.add(69, {baz: 'maybe', bork:'absolutely'});

var obj = WidthRange.getObj();
for (var prop in obj) {
  console.log(obj[prop]);
}

0

काम करने लगता है।

var widthRange = new Array();
widthRange[46] = { sel:46, min:0,  max:52 };
widthRange[66] = { sel:66, min:52, max:70 };
widthRange[90] = { sel:90, min:70, max:94 };

for (var key in widthRange)
{
    document.write(widthRange[key].sel + "<br />");
    document.write(widthRange[key].min + "<br />");
    document.write(widthRange[key].max + "<br />");
}

0

मैंने एक फ़ंक्शन लिखा है जो ऑब्जेक्ट्स के प्रत्येक उदाहरण के साथ ठीक काम करता है (एरोज़ वे हैं)।

Object.prototype.toArray = function()
{
    if(!this)
    {
      return null;
    }

    var c = [];

    for (var key in this) 
    {
        if ( ( this instanceof Array && this.constructor === Array && key === 'length' ) || !this.hasOwnProperty(key) ) 
        {
            continue;
        }

        c.push(this[key]);
    }

    return c;
};

उपयोग:

var a   = [ 1, 2, 3 ];
a[11]   = 4;
a["js"] = 5;

console.log(a.toArray());

var b = { one: 1, two: 2, three: 3, f: function() { return 4; }, five: 5 };
b[7] = 7;

console.log(b.toArray());

आउटपुट:

> [ 1, 2, 3, 4, 5 ]
> [ 7, 1, 2, 3, function () { return 4; }, 5 ]

यह किसी के लिए भी उपयोगी हो सकता है।


2
आपके द्वारा बनाया गया एक प्रोटोटाइप का विस्तार करना बहुत बुरा विचार है, चाहे आप इसे कितना भी सुविधाजनक समझें।
doug65536

0

... ...?

वैकल्पिक रूप से, यदि आपके पास उन वस्तुओं की सूची है, जिनका आप उपयोग करना चाहते हैं ...

var range = [46, 66, 90]
    , widthRange=[]
    , write=[];

    widthRange[46] = { min:0, max:52 }; 
    widthRange[66] = { min:52, max:70 }; 
    widthRange[90] = { min:70, max:94 }; 

for(var x=0; x<range.length; x++){var key, wr;

    key = range[x];

    wr = widthRange[key] || false;

    if(wr===false){continue;}

    write.push(['key: #',key, ', min: ', wr.min, 'max:', wr.max].join(''));

    }

0

आपके इनपुट डेटा के लिए:

let widthRange = new Array()
widthRange[46] = { min:0,  max:52 }
widthRange[61] = { min:52, max:70 }
widthRange[62] = { min:52, max:70 }
widthRange[63] = { min:52, max:70 }
widthRange[66] = { min:52, max:70 }
widthRange[90] = { min:70, max:94 }

घोषणात्मक दृष्टिकोण:

const relevantKeys = [46,66,90]
const relevantValues = Object.keys(widthRange)
    .filter(index => relevantKeys.includes(parseInt(index)))
    .map(relevantIndex => widthRange[relevantIndex])

Object.keysकुंजी प्राप्त करने के लिए, parseIntउन्हें संख्याओं के रूप में उपयोग करने के लिए। filterकेवल वही पाने के लिए जिसे आप चाहते हैं। mapके बाद से आप कर रहे हैं सिर्फ सूचकांकों की मूल वस्तु से एक सरणी बनाने के लिएObject.keysऑब्जेक्ट के मूल्यों को खो ।

डिबग:

console.log(widthRange)
console.log(relevantKeys)
console.log(relevantValues)

0

यह प्रश्न बहुत पुराना है, लेकिन आजकल आप forEach का उपयोग कर सकते हैं, जो कुशल है और संख्याओं के रूप में कुंजियों को बनाए रखेगा:

let keys = widthRange.map((v,k) => k).filter(i=>i!==undefined))

यह चौड़ाई के माध्यम से लूप करता है और कुंजियों के मूल्य के साथ एक नया सरणी बनाता है, और फिर परिभाषित किए गए मानों को ले कर सभी विरल स्लॉट्स को फ़िल्टर करता है।

(बुरा विचार, लेकिन थोरगुनेस के लिए: यदि स्लॉट 0 हमेशा खाली था, जिसे छोटा किया जा सकता है filter(i=>i)याfilter(Boolean)

और, यह कम कुशल हो सकता है, लेकिन संख्या के साथ डाली जा सकती है let keys = Object.keys(array).map(i=>i*1)

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.