2017-10-04 41 views
5

पर निर्भर करता है मैं एक वर्ग MyClassसंग्रह जहां कुंजी मान

class MyClass 
{ 
    public string Name { get; set; } // is unique among all instances 
    public SomeClass Data { get; set; } 
    ... 
} 

जिनमें से मैं एक संग्रह में कई उदाहरण संग्रहीत करना चाहते है। मुझे अक्सर यह जांचने की आवश्यकता होगी कि किसी निश्चित नाम वाला कोई उदाहरण मौजूद है, और यदि ऐसा होता है, तो उस उदाहरण को पुनर्प्राप्त करें। चूंकि पूरे संग्रह के माध्यम से पुनरावृत्ति करना एक विकल्प नहीं है (प्रदर्शन!), मैंने कुंजी-मूल्य-जोड़े के संग्रह का उपयोग करने के बारे में सोचा, उदाहरण के लिए एक IDictionary<string, MyClass>

मेरा प्रोग्राम MyClass के नामकरण उदाहरणों को भी अनुमति देगा (अगर नाम विशिष्टता का उल्लंघन किया जाएगा तो यह नामकरण की अनुमति नहीं देगा)। लेकिन अगर मैं MyClass का नाम बदलता हूं, तो मुझे डेटा को सुसंगत रखने के लिए शब्दकोश से पुरानी प्रविष्टि को हटाने और नए नाम (यानी नए नाम के साथ) को भी हटाने की आवश्यकता होगी।

समस्या यह है कि मेरे पास इस तरह के कई शब्दकोश होंगे (जिसमें सभी MyClass उदाहरणों के सबसेट शामिल हैं), और उन्हें ट्रैक करना मुश्किल होगा और प्रत्येक नामकरण के बाद सभी शब्दकोशों को लगातार अद्यतन करना होगा।

क्या कुंजी-मूल्य जोड़े स्वचालित रूप से लगातार बनाए रखने का कोई तरीका है? मुझे लगता है कि मैंने एक डेटा संरचना के बारे में सुना है जो इसे अनुमति देता है, जो कम से कम C++ में मौजूद है (दुर्भाग्य से, मुझे नहीं पता कि इसे कैसे कहा जाता है)। असल में, यह एक संग्रह होना चाहिए जहां कुंजी केवल एक सादा स्ट्रिंग नहीं है बल्कि एक स्ट्रिंग (इस मामले में नाम संपत्ति के लिए) के संदर्भ की तरह, लेकिन व्यवहार करता है जैसे कि यह एक स्ट्रिंग था। क्या सी # में ऐसी चीज मौजूद है? क्या आपके पास अन्य विचार हैं कि संग्रह को कैसे बनाए रखा जाए?

मेरा एकमात्र विचार है कि मेरे कार्यक्रम के उच्चतम स्तर पर सभी शब्दकोशों का संग्रह होना और वास्तविक नामकरण प्रक्रिया के बाद उन सभी शब्दकोशों को नामकरण विधि अपडेट करना है। लेकिन एक बेहतर तरीका होना चाहिए!


क्यों इस सवाल Best way to change dictionary key का डुप्लिकेट नहीं है:

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

+1

शब्दकोश (या किसी अन्य कुंजी-मूल्य-संग्रह) का उपयोग करते समय आपको यह सुनिश्चित करना चाहिए कि चाबियाँ वही रहें। यही कारण है कि वे संग्रह तेजी से हैं, यह है कि वे चाबियाँ हैंशिंग का उपयोग करते हैं, इस प्रकार कई कुंजियां बहुत तेज पाई जा सकती हैं। यदि आप हैश-फ़ंक्शन में उपयोग किए गए मानों को संशोधित करते हैं तो आप हैश-कार्यक्षमता को पूरी तरह से खो रहे हैं और इस प्रकार प्रदर्शन-लाभ – HimBromBeere

+0

मुझे नहीं लगता कि प्रश्न ऊपर वर्णित एक डुप्लिकेट है और एक उत्तर सुझाएगा (जो डुप्लिकेट लिंक द्वारा दिए गए उत्तर के साथ संगत नहीं है) –

+0

फिर से पूछें, और मैं –

उत्तर

2

जहां तक ​​मेरा आप समझ का कारण होगा, तुम्हारी समस्या क्या है इस:

  • आप एक से अधिक शब्दकोशों है, प्रत्येक अपने डेटा का एक हिस्सा रखती है
  • सभी अपने उदाहरणों जब एक नाम बदल दिया गया है सभी शब्दकोशों
  • भर में एक अद्वितीय नाम होना चाहिए: +०१२३५१६४१०६
    • पहले, इस नाम की जांच अभी भी अद्वितीय
    • अपडेट यह जो कुछ भी

में रहती है dictionray मुझे लगता है कि मैं इस समस्या को थोड़ा अलग से निपटने होता है।

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

[{"FirstName": "Guid1"}, 
{"SecondName": "Guid2"}, 
{"ThirdName": "Guid3"}] 

अपने शब्दकोशों के बाकी उनके कुंजी के रूप में आईडी का आयोजन करेगा, और नहीं नाम:

[{"Guid1": {instance1}}, 
{"Guid2": {instance2}}] 

अब जब आप एक उदाहरण का नाम बदलने, सभी के नाम एक भी शब्दकोश कि आपको बता देंगे अगर यह पहले से ही मौजूद में मौजूद हैं। और आपको इसे केवल एक ही स्थान पर बदलना होगा, क्योंकि शेष शब्दकोष निरंतर मूल्य पर भरोसा करते हैं जो कभी नहीं बदलेगा।
तो तुम "FirstName" का नाम बदलना चाहते हैं कहते हैं, नाम शब्दकोश इस तरह दिखेगा:

[{"OtherName": "Guid1"}, 
{"SecondName": "Guid2"}, 
{"ThirdName": "Guid3"}] 

और डेटा के बाकी को बदलने की जरूरत नहीं है।

1

मुझे नहीं लगता कि ऐसा करने के लिए मूल संग्रह है। हालांकि आप अपनी बेस क्लास में कुछ प्रकार की अधिसूचना जोड़कर आसानी से अपना खुद का निर्माण कर सकते हैं।

public class ChangingNameObject 
    { 
     public delegate void ObjectNameChange(string oldName, string newName); 
     public event ObjectNameChange ObjectNameChanged; 
     private string name; 
     public string Name 
     { 
      get => name; 
      set 
      { 
       ObjectNameChanged?.Invoke(name, value); 
       name = value; 
      } 
     } 
    } 

    public class WatchingDictionary 
    { 
     private Dictionary<string, ChangingNameObject> content = new Dictionary<string, ChangingNameObject>(); 

     public void Add(ChangingNameObject item) 
     { 
      item.ObjectNameChanged += UpdatePosition; 
      content[item.Name] = item; 
     } 

     public void Remove(ChangingNameObject item) 
     { 
      item.ObjectNameChanged -= UpdatePosition; 
      content.Remove(item.Name); 
     } 

     private void UpdatePosition(string oldname, string newname) 
     { 
      var o = content[oldname]; 
      content.Remove(oldname); 
      content.Add(newname, o); 
     } 
    } 

मैंने केवल बहुत ही बुनियादी चीजें लिखीं और आप सभी एक्सेसर्स और एन्युमरेटर्स को याद करते हैं, बस अपनी जरूरत वाले एक को जोड़ें।

हालांकि गणन के साथ बहुत सावधान रहो गणन के दौरान एक संग्रह को बदलने के रूप में एक असफल (और के रूप में संग्रह छिपा हुआ है, youu यह जाने बिना कर किया जा सकता है)

+1

अमूर्त वर्ग 'कीड कोलेक्शन 'इसे कार्यान्वित करने के लिए एक अच्छा कंकाल हो सकता है। – Kjara

+0

हाँ अच्छा बिंदु। मुझे यह नहीं पता था। –

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