एक क्रमबद्ध क्रम में एक जावास्क्रिप्ट साहचर्य सरणी पर Iterate


109

मान लीजिए कि मेरे पास एक जावास्क्रिप्ट एसोसिएटिव सरणी (उर्फ हैश, उर्फ ​​शब्दकोश) है:

var a = new Array();
a['b'] = 1;
a['z'] = 1;
a['a'] = 1;

मैं सॉर्ट किए गए क्रम में कुंजियों पर कैसे पुनरावृति कर सकता हूं? यदि यह चीजों को सरल बनाने में मदद करता है, तो मुझे मूल्यों की आवश्यकता भी नहीं है (वे सभी सिर्फ नंबर 1 हैं)।


11
आप नए ऐरे () निर्माण का उपयोग क्यों कर रहे हैं और फिर उसका उपयोग किसी वस्तु की तरह कर रहे हैं?
ल्यूक शेफर

@ ल्यूक .. मैंने यह पहली बार में भी किया, एक PHP बैकग्राउंड से। मैंने अभी सीखा है :)
एलेक्स

20
@ ल्यूक: 'क्योंकि मैं अनुभवहीन हूँ, ऐसा लगता है। क्या आप उत्तर में सही तरीके से पोस्ट कर सकते हैं?
माइक

4
आप बस किसी भी वस्तु को बना सकते हैं। जावास्क्रिप्ट में शब्दकोश / "नामांकित सरणी" और एक नियमित ऑब्जेक्ट के बीच कोई अंतर नहीं है। इसलिए आप ab और इसके विपरीत एक ['b'] एक्सेस कर सकते हैं। ऑब्जेक्ट बनाने का सबसे छोटा तरीका है a = {};
लोदीविज्क

जवाबों:


124

आप सीधे उन पर पुनरावृत्ति नहीं कर सकते हैं, लेकिन आप सभी कुंजियाँ पा सकते हैं और फिर उन्हें क्रमबद्ध कर सकते हैं।

var a = new Array();
a['b'] = 1;
a['z'] = 1;
a['a'] = 1;    

function keys(obj)
{
    var keys = [];

    for(var key in obj)
    {
        if(obj.hasOwnProperty(key))
        {
            keys.push(key);
        }
    }

    return keys;
}

keys(a).sort(); // ["a", "b", "z"]

हालांकि चर को 'ए' एरे बनाने की कोई आवश्यकता नहीं है। आप वास्तव में इसे एक वस्तु के रूप में उपयोग कर रहे हैं और इसे इस तरह बनाना चाहिए:

var a = {};
a["key"] = "value";

28
आपको हमेशा forलूप में चेक करना चाहिए अगर obj.hasOwnProperty(key)
viam0Zah

3
@ ललित - अगर आप तोरोक की टिप्पणी का उल्लेख कर रहे हैं, ऐसा इसलिए है क्योंकि आपके पास ऑब्जेक्ट के प्रोटोटाइप के साथ कुछ भी हस्तक्षेप नहीं है, जिस पर आप भरोसा नहीं कर सकते।
ल्यूक शेफर

1
+1 से तोरोक। यह अच्छा होगा यदि उत्तर में hasOwnProperty () शामिल हो।
जॉन ऑनस्टॉट सेप

136

आप ऑब्जेक्ट में निर्मित विधि का उपयोग कर सकते हैं :

var sorted_keys = Object.keys(a).sort()

(नोट: यह बहुत पुराने ब्राउज़रों में काम नहीं करता है जो EcmaScript5 का समर्थन नहीं करते हैं, विशेष रूप से IE6, 7 और 8. विस्तृत अप-टू-डेट आंकड़ों के लिए, यह तालिका देखें )


@ माइकल 667 शायद इसलिए क्योंकि IE 7 और 8 अभी भी व्यापक रूप से उपयोग किए जाते हैं (दुर्भाग्य से, धन्यवाद एमएस)
अलेक्जेंडर रिफिंगर

1
IE7 0.5% पर है और IE8 अब सौभाग्य से 8% पर है।
मोलारनग

3
if (!Object.keys) { Object.keys = function (obj) { var op, result = []; for (op in obj) { if (obj.hasOwnProperty(op) { result.push(op) } } return result }
जॉर्डन रीटर

मैं इस एक प्यार करता हूँ, धन्यवाद। यहाँ मेरा कोड इस का लाभ उठा रहा है, $ (Object.keys (सूची))। नक्शा (फ़ंक्शन (i, e) {रिटर्न n + '=' सूची [n];})। get () शामिल हों ('&'); // यूआरएल क्वेरी स्ट्रिंग के लिए concat
ऐलेन

1
2016 अपडेट: यह संभवतः स्वीकृत उत्तर होना चाहिए
रिनोगो

14

आप इसे ऑब्जेक्ट पर भी प्रोटोटाइप कर सकते हैं:

Object.prototype.iterateSorted = function(worker)
{
    var keys = [];
    for (var key in this)
    {
        if (this.hasOwnProperty(key))
            keys.push(key);
    }
    keys.sort();

    for (var i = 0; i < keys.length; i++)
    {
        worker(this[ keys[i] ]);
    }
}

और उपयोग:

var myObj = { a:1, b:2 };
myObj.iterateSorted(function(value)
{
    alert(value);
} 

3
मैंने इस उत्तर को उतारा यह काफी अच्छा लग रहा था, लेकिन यह पता चला कि यह jquery को तोड़ता है :( stackoverflow.com/questions/1827458/… और सामान्य रूप से एक बहुत बुरा विचार माना जाता है "आपको Object.prototype का विस्तार कभी नहीं करना चाहिए। ब्रेक jQuery, यह पूरी तरह से जावास्क्रिप्ट के "ऑब्जेक्ट-ए-हैशटैबल्स" फीचर को तोड़ता है। ऐसा न करें। आप जॉन रेजिग से पूछ सकते हैं, और वह आपको एक ही बात बताएगा। "
msanjay

आपको पता है कि? मुझे प्रोटोटाइप से भी नफरत है :) मैं कभी भी उनका उपयोग नहीं करता और सक्रिय रूप से उनके उपयोग को हतोत्साहित करता हूं। मैंने 3.5 साल पहले इस तरह से महसूस किया था जब मैंने यह जवाब लिखा था, लेकिन इसे वैसे भी सुझाव दिया था ... जानकारी प्रदान करने के लिए धन्यवाद। एक तरफ के रूप में, यह रूपरेखाओं को तोड़ना चाहिए क्योंकि जब वस्तुओं को पुनरावृत्त करना चाहिए, तो उन्हें हमेशा उपयोग करना चाहिए
ल्यूक

यहाँ एक उदाहरण है कि वेkey -> value रिश्तों को बनाए रखते हुए छँटाई के बजाय मूल्यों का उपयोग करते हैं
Xeoncross 15

6

मैं स्विंगली के उत्तर से सहमत हूं , और मुझे लगता है कि यह एक महत्वपूर्ण बिंदु है कि इनमें से अधिक विस्तृत समाधान गायब हैं। यदि आप केवल साहचर्य सरणी में कुंजियों से संबंधित हैं और सभी मान '1' हैं, तो 'कुंजियों' को एक सरणी में मानों के रूप में संग्रहीत करते हैं।

के बजाय:

var a = { b:1, z:1, a:1 };
// relatively elaborate code to retrieve the keys and sort them

उपयोग:

var a = [ 'b', 'z', 'a' ];
alert(a.sort());

इसका एक दोष यह है कि आप यह निर्धारित नहीं कर सकते हैं कि एक विशिष्ट कुंजी आसानी से सेट की गई है या नहीं। उस समस्या के उत्तर के लिए जावास्क्रिप्ट फ़ंक्शन के लिए यह उत्तर देखें । प्रस्तुत समाधान के साथ एक मुद्दा यह है कि a.hasValue('key')की तुलना में थोड़ा धीमा होने जा रहा है a['key']। आपके कोड में यह बात या नहीं भी हो सकती है।


3

जावास्क्रिप्ट ऑब्जेक्ट की "कुंजियों" को सीधे हेरफेर करने का कोई संक्षिप्त तरीका नहीं है। यह वास्तव में उस के लिए डिज़ाइन नहीं किया गया है। क्या आपको अपने डेटा को एक नियमित वस्तु (या एक ऐरे) से बेहतर बनाने की स्वतंत्रता है, जैसा कि आपका नमूना कोड बताता है)?

यदि ऐसा है, और यदि आपका प्रश्न "क्या शब्दकोश जैसी वस्तु का उपयोग करना चाहिए, तो क्या मुझे छांटे गए क्रम में कुंजियों पर पुनरावृति करना चाहिए?" तो आप इस तरह एक वस्तु विकसित कर सकते हैं:

var a = {
  keys : new Array(),
  hash : new Object(),
  set : function(key, value) {
    if (typeof(this.hash[key]) == "undefined") { this.keys.push(key); }
    this.hash[key] = value;
  },
  get : function(key) {
    return this.hash[key];
  },
  getSortedKeys : function() {
    this.keys.sort();
    return this.keys;
  }
};

// sample use
a.set('b',1);
a.set('z',1);
a.set('a',1);
var sortedKeys = a.getSortedKeys();
for (var i in sortedKeys) { print(sortedKeys[i]); }

यदि आपके पास इस तथ्य पर कोई नियंत्रण नहीं है कि डेटा एक नियमित ऑब्जेक्ट में है, तो यह उपयोगिता नियमित ऑब्जेक्ट को आपके पूर्ण-कार्यात्मक शब्दकोश में बदल देगी:

a.importObject = function(object) {
  for (var i in object) { this.set(i, object); }
};

यह सादगी के लिए एक वस्तु परिभाषा (एक पुन: प्रयोज्य निर्माण कार्य के बजाय) थी; वसीयत में संपादित करें।


2

पहले forलूप में कुंजी प्राप्त करें , इसे सॉर्ट करें, 2 forलूप में सॉर्ट किए गए परिणाम का उपयोग करें ।

var a = new Array();
a['b'] = 1;
a['z'] = 1;
a['a'] = 1;

var b = [];
for (k in a) b.push(k);
b.sort();
for (var i = 0; i < b.length; ++i) alert(b[i]);

2

आप चाबियाँ प्राप्त करने के लिए underscore.js लाइब्रेरी keysसे फ़ंक्शन का उपयोग कर सकते हैं , फिर उन्हें सॉर्ट करने के लिए सरणी विधि:sort()

var sortedKeys = _.keys(dict).sort();

keysअंडरस्कोर के स्रोत कोड में समारोह:

// Retrieve the names of an object's properties.
// Delegates to **ECMAScript 5**'s native `Object.keys`
_.keys = nativeKeys || function(obj) {
    if (obj !== Object(obj)) throw new TypeError('Invalid object');
    var keys = [];
    for (var key in obj) if (_.has(obj, key)) keys.push(key);
    return keys;
};    

// Shortcut function for checking if an object has a given property directly
// on itself (in other words, not on a prototype).
_.has = function(obj, key) {
    return hasOwnProperty.call(obj, key);
};

0
<script type="text/javascript">
    var a = {
        b:1,
        z:1,
        a:1
    }; // your JS Object
    var keys = [];
    for (key in a) {
        keys.push(key);
    }
    keys.sort();
    var i = 0;
    var keyslen = keys.length;
    var str = '';
    //SORTED KEY ITERATION
    while (i < keyslen) {
        str += keys[i] + '=>' + a[keys[i]] + '\n';
        ++i;
    }
    alert(str);
    /*RESULT:
    a=>1
    b=>1
    z=>1
    */
</script>


0

मैं वास्तव में @ luke-schafer के प्रोटोटाइप विचार को पसंद करता हूं, लेकिन यह भी सुनता हूं कि वह प्रोटोटाइप के साथ मुद्दों के बारे में क्या कह रहा है। एक साधारण फ़ंक्शन का उपयोग करने के बारे में क्या?

function sortKeysAndDo( obj, worker ) {
  var keys = Object.keys(obj);
  keys.sort();
  for (var i = 0; i < keys.length; i++) {
     worker(keys[i], obj[keys[i]]);
  }
}

function show( key, value ) {
  document.write( key + ' : ' + value +'<br>' );
}

var a = new Array();
a['b'] = 1;
a['z'] = 1;
a['a'] = 1;

sortKeysAndDo( a, show);

var my_object = { 'c': 3, 'a': 1, 'b': 2 };

sortKeysAndDo( my_object, show);

यह प्रोटोटाइप के साथ मुद्दों को खत्म करने के लिए लगता है और अभी भी वस्तुओं के लिए एक क्रमबद्ध पुनरावृत्ति प्रदान करता है। मैं वास्तव में एक जावास्क्रिप्ट गुरु नहीं हूं, हालांकि, मुझे यह जानना अच्छा लगेगा कि क्या इस समाधान में छिपी हुई खामियां हैं जो मुझे याद हैं।

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