2010-03-05 16 views

उत्तर

32

एएस 3 डिक्शनरी के आकार/लंबाई/गिनती के लिए कोई अंतर्निहित विधि नहीं है। वर्कअराउंड्स हैं: उदाहरण के लिए, आप एक कस्टम डिक्शनरी क्लास बना सकते हैं जो काउंटर कार्यक्षमता जोड़कर flash.utils.Dictionary कक्षा को बढ़ाता या लपेटता है। आप गिनती प्रबंधन कर सकते हैं के रूप में प्रविष्टियों जोड़ा गया/निकाला जाता है, या पाश यात्रा के लिए एक सरल का उपयोग कर मांग पर गिनती:

public static function countKeys(myDictionary:flash.utils.Dictionary):int 
{ 
    var n:int = 0; 
    for (var key:* in myDictionary) { 
     n++; 
    } 
    return n; 
} 
+1

बहुत खराब है, एक आवरण का निर्माण करने के लिए किया था। –

+47

मैं ऐसा करने के लिए एडोब को डाउनवोट करने के लिए कहां जाऊं? –

+1

फॉर लूप में गॉथस से बचने के लिए जरूरी था, यानी क्या होता है जब for..in के साथ ऐरे पर लूपिंग होती है। – Brilliand

0

एक आदर्श सिर्फ शब्दकोश के चारों ओर एक आवरण है कि प्रॉक्सी वर्ग फैली लागू करेगा। इससे आपको डिक्शनरी से गुणों को जोड़ने और हटाने में मदद मिलती है, जिससे नई डिक्शनरी क्लास को सटीक उसी वाक्यविन्यास और क्षमताओं के साथ मूल रूप से मूल रूप से उपयोग करने की इजाजत मिलती है, जिसमें लम्बाई फ़ंक्शन भी शामिल होता है जो संख्या की संख्या देता है चांबियाँ।

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

मैंने इस प्रश्न के लिए इस शब्दकोश रैपर को लिखा है; इसमें लगभग 5 मिनट लग गए, और यह एक लम्बा कार्य प्रदान करता है जो लंबाई देता है। मैंने इसे किसी संपत्ति के बजाय एक फ़ंक्शन बनाने का विकल्प चुना है ताकि यह संपत्ति के नामों या शब्दकोश की गुणों की गणना में हस्तक्षेप न करे।

इस कार्यान्वयन का उपयोग न करें; इसका उपयोग करें जो इसे स्थापित करता है। मैं नीचे क्यों समझाता हूं।

package flos.utils 
{ 
    import flash.utils.flash_proxy; 
    import flash.utils.Proxy; 

    public class Dictionary extends Proxy 
    { 
     private var d:flash.utils.Dictionary; 
     private var _length:int = 0; 

     public function Dictionary(weakKeys:Boolean = false) 
     { 
      d = new flash.utils.Dictionary(weakKeys); 
     } 

     public function length():int 
     { 
      return _length; 
     } 

     override flash_proxy function getProperty(name:*):* 
     { 
      return d[name]; 
     } 

     override flash_proxy function setProperty(name:*, value:*):void 
     { 
      if (value === undefined) //delete property when explicitly set to undefined, to enforce rule that an undefined property does not exist and is not counted 
      { 
       delete this[name]; 
       return; 
      } 
      if (d[name] === undefined) 
       _length++; 
      d[name] = value; 
     } 

     override flash_proxy function deleteProperty(name:*):Boolean 
     { 
      if (d[name] !== undefined) 
      { 
       delete d[name]; 
       _length--; 
       return true; 
      } 
      return false; 
     } 
    } 
} 

अस्वीकरण: कार्यान्वयन ऊपर है, हालांकि सबसे होनहार दृष्टिकोण है जो सिद्धांत रूप में काम कर सकते थे, अंत में, एक मृत अंत है, क्योंकि शब्दकोश प्रॉक्सी इंटरफ़ेस तरीकों के साथ स्वाभाविक असंगत है।

पहले, setProperty, getProperty, और deleteProperty तरीकों untyped name पैरामीटर प्राप्त करने के लिए दिखाई देते हैं, लेकिन वे वास्तव में कर रहे हैं दृढ़ता से QName वस्तुओं, जो अनिवार्य सिर्फ Object और सहयोगी सरणी की तरह, String प्रकार के नाम करने के लिए अपनी चाबी प्रतिबंधित टाइप किया है। Dictionary इस सीमा से बंधे नहीं है और ऑब्जेक्ट उदाहरणों को अद्वितीय कुंजी के रूप में उपयोग करने की अनुमति देता है, इसलिए यह प्रॉक्सी क्लास विधियों के साथ मूल रूप से असंगत है। डिक्शनरी क्लास के दस्तावेज में एक भी नोट है, और यह स्पष्ट रूप से कहता है कि QName ऑब्जेक्ट्स को चाबियों के रूप में उपयोग नहीं किया जा सकता है।

इसी तरह, प्रॉक्सी के nextName विधि, इसी कारण से सभी Dictionary चाबियाँ पर गणना करने से रोकता है, क्योंकि यह String की एक जोरदार प्रकार वापसी मान है। तो अगर setProperty, getProperty वास्तव में नामों के लिए अनचाहे कुंजी स्वीकार कर लिया गया है, तो भी आप उन्हें गणना के माध्यम से पुनर्प्राप्त नहीं कर पाएंगे क्योंकि nextName विधि केवल प्रकार स्ट्रिंग लौटाती है। Dictionary बस अपनी खुद की एक कक्षा में है।

सबसे अच्छी बात यह है कि आप ऊपर की तरह एक रैपर को लागू कर सकते हैं जो गणना के लिए अंतर्निहित शब्दकोश को उजागर करता है, लेकिन दूसरों को प्रॉक्सी व्यवहार का उपयोग करने के बजाय, स्पष्ट नामों और मूल्यों के साथ स्पष्ट addKey/removeKey विधियों को कॉल करने की आवश्यकता होती है।

देखते हुए ऊपर के सभी, एक बेहतर कार्यान्वयन इस प्रकार हो सकता है, जहां इस तरह के getValue/setValue/removeValue तरीके के रूप में फोन करके शब्दकोश में हेरफेर, और एक कुंजी गणना करने के साथ ही लंबाई संपत्ति उपयोग कर सकते है:

public class Dictionary 
{ 
    private var d:flash.utils.Dictionary; 
    private var _keys:Array; 

    public function Dictionary(weakKeys:Boolean = false) 
    { 
     d = new flash.utils.Dictionary(weakKeys); 
     _keys = new Array(); 
    } 

    public function get keys():Array 
    { 
     return _keys.concat(); //return copy of keys array 
    } 

    public function get length():int 
    { 
     return _keys.length; 
    } 

    public function containsKey(key:*):Boolean 
    { 
     return d[key] !== undefined; 
    } 

    public function setValue(key:*, value:*):void 
    { 
     if (value === undefined) //delete property when explicitly set to undefined, to enforce rule that an undefined property does not exist and is not counted 
     { 
      removeValue(key); 
      return; 
     } 
     if (d[key] === undefined) 
     { 
      _keys.push(key); 
     } 
     d[key] = value; 
    } 

    public function getValue(key:*):* 
    { 
     return d[key]; 
    } 

    public function removeValue(key:*):Boolean 
    { 
     if (d[key] !== undefined) 
     { 
      delete d[key]; 
      var i:int = _keys.indexOf(key); 
      if (i > -1) 
       _keys.splice(i, 1); 
      return true; 
     } 
     return false; 
    } 
0

आप DictionaryUtil उपयोग कर सकते हैं:

var dictionaryLength : int = DictionaryUtil.getKeys(d).length; 
संबंधित मुद्दे