2009-05-20 14 views
102

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

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

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

+10

आप नए ऐरे() निर्माण का उपयोग क्यों कर रहे हैं और फिर किसी ऑब्जेक्ट की तरह इसका उपयोग कर रहे हैं? –

+0

@ ल्यूक .. मैंने इसे पहले भी किया, एक PHP पृष्ठभूमि से आ रहा था। मैंने अभी सीखा है :) – alex

+19

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

उत्तर

121

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

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

यदि आपको 'obj.hasOwnProperty (key)' 'लूप में हमेशा जांचना चाहिए। –

+0

यह मेरे लिए काम कर रहा है। –

+3

@ ललित - यदि आप टोरोक की टिप्पणी का जिक्र कर रहे हैं, तो ऐसा इसलिए है क्योंकि आपके पास ऑब्जेक्ट के प्रोटोटाइप में हस्तक्षेप नहीं है, जिस पर आप भरोसा नहीं कर सकते। –

2

पहले for लूप में कुंजी प्राप्त करें, इसे सॉर्ट करें, सॉर्ट किए गए परिणाम का उपयोग दूसरे 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

(के में बी) किसी सरणी पर मुद्दों का कारण बन जाएगा। एक पूर्णांक –

+0

के साथ Iterate मैं पिछली पंक्ति में डर रहा हूं जिसे आप सरणी 'बी' पर पुन: सक्रिय करना चाहते हैं, और' k' नहीं जिसे आपने सरणी 'ए' के ​​वर्तमान मान को पकड़ने के लिए उपयोग किया था। –

+0

सभी फिक्स के लिए धन्यवाद। – pts

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); 
} 
+1

चूंकि जावास्क्रिप्ट केस-संवेदी है, इसलिए आपको 'ऑब्जेक्ट' शब्द को कैपिटल करना चाहिए, क्योंकि 'टाइपऑफ ऑब्जेक्ट // अपरिभाषित'। –

+0

हां। वह एक टाइपो था :) –

+0

सिंटेक्स सुधार: 'हैऑनप्रॉपर्टी' एक फ़ंक्शन है, इसलिए इसे पैरों की आवश्यकता होती है, स्क्वायर ब्रैकेट नहीं। मुझे इतना छोटा संपादन करने की अनुमति नहीं थी। –

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

सादगी के लिए यह एक ऑब्जेक्ट परिभाषा (पुन: प्रयोज्य कन्स्ट्रक्टर फ़ंक्शन की बजाय) थी; इच्छा पर संपादित करें।

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> 
6

मैं Swingley's answer से सहमत हैं, और मुझे लगता है कि यह एक महत्वपूर्ण बिंदु इन और अधिक व्यापक समाधान का एक बहुत याद कर रहे हैं है। यदि आप केवल एसोसिएटिव सरणी में चाबियों से चिंतित हैं और सभी मान '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()); 

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

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

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

121

आप Object.keys निर्मित विधि का उपयोग कर सकते हैं सांख्यिकी, this table देखें)

+5

यह उत्तर अधिक अपवित्र क्यों नहीं है? – michael667

+0

@ michael667 शायद क्योंकि आईई 7 और 8 अभी भी व्यापक रूप से उपयोग किए जाते हैं (दुर्भाग्यवश, धन्यवाद एमएस) –

+1

आईई 7 0.5% पर है और आईई 8 अब सौभाग्य से 8% है। – molnarg

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

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

 

 
var keys=Object.keys(a).sort(); 
 
for(var i=0,key=keys[0];i<keys.length;key=keys[++i]){ 
 
    document.write(key+' : '+a[key]+'<br>'); 
 
}

0

मैं वास्तव @ ल्यूक-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);

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

संबंधित मुद्दे