2009-07-02 19 views
36

जेएस में एक सरणी सहयोगी और अनुक्रमित हो सकता है? मैं सरणी में किसी आइटम को उसकी स्थिति या एक प्रमुख मान से देखने में सक्षम होना चाहता हूं .. संभव है?जावास्क्रिप्ट सरणी सहयोगी और अनुक्रमित?

+0

इस सुंदर पुराना है, लेकिन आप Object.keys (सरणी) का उपयोग कुंजी आदेश –

+1

में आप एक PHP प्रोग्रामर :) – nawfal

उत्तर

6

ऑब्जेक्टिव जावास्क्रिप्ट सरणी में ऑब्जेक्ट्स में प्रकट होने वाले क्रम को परिभाषित नहीं किया गया है, और विभिन्न कार्यान्वयनों में भिन्न होगा। इसी कारण से आप वास्तव में एक ही इंडेक्स पर हमेशा रहने के लिए किसी दिए गए सहयोगी कुंजी पर भरोसा नहीं कर सकते हैं।

संपादित करें:

रूप Perspx बताते हैं, वहाँ वास्तव में जावास्क्रिप्ट में सच साहचर्य सरणियों नहीं हैं। बयान foo["bar"] के लिए foo.bar

आप ब्राउज़र पर विश्वास करते हैं एक वस्तु में तत्वों की व्यवस्था बनाए रखने के लिए, आप एक समारोह लिख सकता है बस वाक्यात्मक चीनी है

function valueForIndex(obj, index) { 

    var i = 0; 
    for (var key in obj) { 

     if (i++ == index) 
      return obj[key]; 
    } 
} 
+3

यद्यपि यह एक सच है कर रहे हैं पाने के लिए कर सकते हैं, व्यावहारिक रूप से ऑब्जेक्ट के गुणों पर सभी प्रमुख ब्राउज़र लूप को क्रम में परिभाषित किया गया था। यह निश्चित रूप से कल्पना में नहीं है, लेकिन यह उल्लेखनीय है। –

+0

+1 आपका सुझाव सबसे तेज़ तरीका है! – mate64

26

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

उदाहरण के लिए

, इस उद्देश्य के साथ:

var params = { 
    foo: 1, 
    bar: 0, 
    other: 2 
}; 

आप वस्तु से गुण का उपयोग कर सकते, उदाहरण के लिए:

params["foo"]; 

और तुम भी for...in कथन का उपयोग वस्तु पर पुनरावृति कर सकते हैं:

for(var v in params) { 
    //v is equal to the currently iterated property 
} 

हालांकि, संपत्ति के आदेश पर कोई सख्त नियम नहीं है पुनरावृत्ति - आपके ऑब्जेक्ट का दो पुनरावृत्तियों शाब्दिक गुणों को विभिन्न ऑर्डर में वापस कर सकता है।

+1

दरअसल, जावास्क्रिप्ट सरणी में गैर-पूर्णांक सूचकांक भी हो सकते हैं। यह उनके साथ निपटने के तरीकों के रास्ते में ज्यादा नहीं है। – Nosredna

+3

आपका मतलब स्ट्रिंग की तरह है? उस स्थिति में यह एक सरणी नहीं है, केवल संपत्तियों के साथ एक वस्तु है। – roryf

+3

नोस्रेना: जेएस सरणी में महत्वपूर्ण सूचकांक नहीं हैं, उन जेएस ऑब्जेक्ट्स को ऑब्जेक्ट अक्षर कहा जाता है। तो: foo ["bar"] = 1; foo.bar === foo ["bar"]; // सच foo ["bar"] === foo [0]; // झूठी यह जेएस के बारे में कई सूक्ष्म quirks में से एक है जो लोगों को आसानी से फेंक देता है। – linusthe3rd

20

Wikipedia definition of associative array पढ़ने के बाद, मैं पारंपरिक जावास्क्रिप्ट लोअर के साथ तोड़ने जा रहा हूं और कहूंगा, "हाँ, जावास्क्रिप्ट में सहयोगी सरणी हैं।" जावास्क्रिप्ट सरणी के साथ, आप अपनी चाबियों द्वारा मूल्यों को जोड़, पुन: असाइन, हटा सकते हैं और लुकअप कर सकते हैं (और चाबियों को तारों को उद्धृत किया जा सकता है), जो कि विकिपीडिया का कहना है कि सहयोगी सरणी करने में सक्षम होना चाहिए।

हालांकि, आप कुछ अलग पूछ रहे हैं - चाहे आप इंडेक्स या कुंजी द्वारा समान मूल्य देख सकें। यह सहयोगी सरणी की आवश्यकता नहीं है (विकिपीडिया लेख देखें।) एसोसिएटिव सरणी आपको इंडेक्स द्वारा मूल्य प्राप्त करने की क्षमता नहीं देनी पड़ती है।

JavaScript arrays are very closely akin to JavaScript objects.

arr=[]; 
    arr[0]="zero"; 
    arr[1]="one"; 
    arr[2]="two"; 
    arr["fancy"]="what?"; 

हाँ, वह एक सरणी है, और हाँ, आप गैर-संख्यात्मक सूचकांक के साथ भाग प्राप्त कर सकते हैं। (यदि आप उत्सुक हैं, तो इसके बाद, arr.length है 3.)

ज्यादातर मामलों में, मुझे लगता है कि जब आप सरणी का उपयोग करते हैं तो आपको संख्यात्मक सूचकांक में रहना चाहिए। मुझे लगता है कि ज्यादातर प्रोग्रामर क्या उम्मीद करते हैं।

लिंक इस विषय के बारे में मेरे ब्लॉग पोस्ट के लिए है।

+0

आप सही थे जब आपने कहा था "और आपके पास गैर-संख्यात्मक सूचकांक वाले सरणी हो सकती है"। यह किसी भी तरह से मेरे दिमाग फिसल गया, लेकिन मैं इस तथ्य को जानता हूँ। –

+13

pedantic होने के लिए, "फैंसी" सरणी में एक सूचकांक नहीं है, लेकिन सरणी उदाहरण वस्तु का एक विशेषता है। – BaroqueBobcat

+0

हाँ, अच्छा बिंदु। यही कारण है कि मैं कहता हूं कि सरणी जावास्क्रिप्ट में वस्तुओं से बारीकी से संबंधित हैं। – Nosredna

9

मूल जेएस ऑब्जेक्ट केवल स्ट्रिंग को संपत्ति नाम के रूप में स्वीकार करते हैं, जो सच है even for numeric array indices; सरणी केवल वेनिला ऑब्जेक्ट्स से अलग होती हैं क्योंकि अधिकांश जेएस कार्यान्वयन संख्यात्मक रूप से अनुक्रमित गुणों को अलग-अलग स्टोर करते हैं (यानि एक वास्तविक सरणी में जब तक वे घने होते हैं) और उन्हें सेट करने से अतिरिक्त परिचालन (जैसे length संपत्ति का समायोजन) ट्रिगर होगा।

यदि आप एक ऐसे मानचित्र की तलाश में हैं जो मनमाने ढंग से कुंजी स्वीकार करता है, तो आपको non-native implementation का उपयोग करना होगा। लिपि तेजी से पुनरावृत्ति के लिए है और संख्यात्मक सूचकांक द्वारा यादृच्छिक-पहुंच नहीं है, इसलिए यह न हो और न ही आप जो खोज रहे हैं।

मानचित्र का एक barebones कार्यान्वयन जो आप जो चाह रहे हैं ऐसा दिखाई दे सकता करना होगा:

function Map() { 
    this.length = 0; 
    this.store = {}; 
} 

Map.prototype.get = function(key) { 
    return this.store.hasOwnProperty(key) ? 
     this.store[key] : undefined; 
}; 

Map.prototype.put = function(key, value, index) { 
    if(arguments.length < 3) { 
     if(this.store.hasOwnProperty(key)) { 
      this.store[key].value = value; 
      return this; 
     } 

     index = this.length; 
    } 
    else if(index >>> 0 !== index || index >= 0xffffffff) 
     throw new Error('illegal index argument'); 

    if(index >= this.length) 
     this.length = index + 1; 

    this[index] = this.store[key] = 
     { index : index, key : key, value : value }; 

    return this; 
}; 

put() की index तर्क वैकल्पिक है।

आप के माध्यम से

map.get('key').value 
map[2].value 
+0

+1, लेकिन मैं हार जाऊंगा "संख्यात्मक रूप से अनुक्रमित गुण अलग-अलग संग्रहीत किए जाएंगे": यह आवश्यक नहीं है, और spec द्वारा आवश्यक नहीं है। – Miles

+0

@ मील: [x] किया – Christoph

+0

आप कैसे डालते हैं? map.put ('key', 'value') और मानचित्र [2] .value = val? किसी दिए गए स्थान पर मूल्य डालने के लिए – Chris

1
var stuff = []; 
stuff[0] = "foo"; 
stuff.bar = stuff[0]; // stuff.bar can be stuff["bar"] if you prefer 
var key = "bar"; 
alert(stuff[0] + ", " + stuff[key]); // shows "foo, foo" 
+0

इस तरह नई प्रविष्टियां जोड़ सकते हैं लेकिन फिर सामान। लम्बाई 1 और नहीं होगा क्योंकि आपने जोड़ा .bar सही? इस प्रकार इंडेक्स द्वारा लूपिंग वास्तव में अब काम नहीं करेगा .. – puffpio

+1

नहीं - नामित संपत्ति जोड़ना लंबाई में वृद्धि नहीं करता है; केवल संख्यात्मक सूचकांक द्वारा एक तत्व जोड़ना लंबाई बढ़ जाती है। "सामान [1000] = 'blah'" जोड़ना लंबाई 1001 तक बढ़ने का कारण बनता है, भले ही केवल दो संख्यात्मक रूप से अनुक्रमित तत्वों और एक नामित संपत्ति को वास्तव में जोड़ा गया हो। मज़ा यह नहीं है ;-) – NickFitz

-2

मानचित्र map या तो कुंजी या सूचकांक द्वारा में मानों का उपयोग कर सकते हां।

test = new Array(); 
test[0] = 'yellow'; 
test['banana'] = 0; 
alert(test[test['banana']]); 
0

हालांकि मैं दिए गए उत्तरों से सहमत हूं, लेकिन आप वास्तव में प्राप्तकर्ताओं और सेटर्स के साथ जो कह रहे हैं उसे पूरा कर सकते हैं। उदाहरण के लिए:

var a = [1]; 
//This makes a["blah"] refer to a[0] 
a.__defineGetter__("blah", function(){return this[0]}); 
//This makes a["blah"] = 5 actually store 5 into a[0] 
a.__defineSetter__("blah", function(val){ this[0] = val}); 

alert(a["blah"]); // emits 1 
a["blah"] = 5; 
alert(a[0]); // emits 5 

क्या आप यह देख रहे हैं? मुझे लगता है कि गेटर्स और सेटर्स करने के लिए एक और अधिक आधुनिक तरीका है लेकिन याद नहीं है।

+0

ओह और यदि आप इसे एक लूप में करने जा रहे हैं तो आपको बंद होने की आवश्यकता होगी ... बस कह रहा है। – Ryan

4
var myArray = Array(); 
myArray["first"] = "Object1"; 
myArray["second"] = "Object2"; 
myArray["third"] = "Object3"; 

Object.keys(myArray);    // returns ["first", "second", "third"] 
Object.keys(myArray).length;  // returns 3 

यदि आप पहले तत्व चाहते हैं तो आप ऐसा की तरह उपयोग कर सकते हैं:

myArray[Object.keys(myArray)[0]]; // returns "Object1" 
0

मैं अगर यह बुरा व्यवहार है या नहीं जानने की चाह करने के लिए यहाँ आया था, और इसके बजाय बहुत से लोगों को मिल गया सवाल समझने के लिए प्रकट नहीं हो रहा है।

मैं एक डेटा संरचना चाहता था जिसे आदेश दिया गया था लेकिन कुंजी द्वारा अनुक्रमित किया जा सकता था, ताकि उसे प्रत्येक लुकअप के लिए पुनरावृत्ति की आवश्यकता न हो।

मैं व्यावहारिक समय यह काफी सरल है, लेकिन मैंने अभी भी कुछ भी नहीं पढ़ा है कि यह एक भयानक अभ्यास है या नहीं।

var roygbiv = []; 
var colour = { key : "red", hex : "#FF0000" }; 
roygbiv.push(colour); 
roygbiv[colour.key] = colour; 
... 
console.log("Hex colours of the rainbow in order:"); 
for (var i = 0; i < roygbiv.length; i++) { 
    console.log(roygbiv[i].key + " is " + roygbiv[i].hex); 
} 

// input = "red"; 
console.log("Hex code of input colour:"); 
console.log(roygbiv[input].hex); 

महत्वपूर्ण बात यह सरणी के मूल्य कभी नहीं बदलने के लिए है [सूचकांक] या सरणी [कुंजी] सीधे एक बार वस्तु की स्थापना या मान नहीं करेगा मैच है। यदि सरणी में ऑब्जेक्ट्स हैं तो आप उन ऑब्जेक्ट्स के गुणों को बदल सकते हैं और आप किसी भी विधि से बदले गए गुणों तक पहुंच पाएंगे।

0

इस पर ज्वार बदल गया है। अब आप यह कर सकते हैं ... और अधिक! सद्भावना प्रॉक्सी का उपयोग करके आप निश्चित रूप से इस समस्या को कई तरीकों से हल कर सकते हैं।

आपको यह सत्यापित करना होगा कि आपके लक्षित वातावरण harmony-reflect शिम से थोड़ी सी सहायता के साथ इसका समर्थन करते हैं।

मोज़िला डेवलपर नेटवर्क पर find an array item object by it's property पर प्रॉक्सी का उपयोग करने पर वास्तव में एक अच्छा उदाहरण है जो काफी अधिक है।

यहाँ मेरी संस्करण है:

var players = new Proxy(
    [{ 
    name: 'monkey', 
    score: 50 
    }, { 
    name: 'giraffe', 
    score: 100 
    }, { 
    name: 'pelican', 
    score: 150 
    }], { 
    get: function(obj, prop) { 
     if (prop in obj) { 
     // default behavior 
     return obj[prop]; 
     } 
     if (typeof prop == 'string') { 

     if (prop == 'rank') { 
      return obj.sort(function(a, b) { 
      return a.score > b.score ? -1 : 1; 
      }); 
     } 

     if (prop == 'revrank') { 
      return obj.sort(function(a, b) { 
      return a.score < b.score ? -1 : 1; 
      }); 
     } 

     var winner; 
     var score = 0; 
     for (var i = 0; i < obj.length; i++) { 
      var player = obj[i]; 
      if (player.name == prop) { 
      return player; 
      } else if (player.score > score) { 
      score = player.score; 
      winner = player; 
      } 
     } 

     if (prop == 'winner') { 
      return winner; 
     } 
     return; 
     } 

    } 
    }); 

    console.log(players[0]); // { name: 'monkey', score: 50 } 
    console.log(players['monkey']); // { name: 'monkey', score: 50 } 
    console.log(players['zebra']); // undefined 
    console.log(players.rank); // [ { name: 'pelican', score: 150 },{ name: 'giraffe', score: 100 }, { name: 'monkey', score: 50 } ] 
    console.log(players.revrank); // [ { name: 'monkey', score: 50 },{ name: 'giraffe', score: 100 },{ name: 'pelican', score: 150 } ] 
    console.log(players.winner); // { name: 'pelican', score: 150 } 
संबंधित मुद्दे