2009-05-15 8 views
5

मैं संरचना इस तरह का उपयोग करने के लिए होता है काफी एक बहुत कुछ:सी # में सूची के शब्दकोशों को शुरू करने के दर्द को मैं कैसे कम कर सकता हूं?

Dictionary<string, List<string>> Foo = new Dictionary<string, List<string>>(); 

कौन सा कोड के इस प्रकार की ओर जाता है:

foreach (DataRow dr in ds.Tables[0].Rows) 
{ 
    List<string> bar; 
    if (!Foo.TryGetValue(dr["Key"].ToString(), out desks)) 
    { 
     bar= new List<string>(); 
     Foo.Add(dr["Key"].ToString(), bar); 
    } 
    bar.Add(dr["Value"].ToString()); 
} 

क्या आपको लगता है यह एक कस्टम DictionaryOfList वर्ग लेखन के लायक जो इस संभाल होता है चीजों की तरह स्वचालित रूप से?

क्या उन सूचियों को आलसी शुरू करने का कोई और तरीका है?

foreach (DataRow dr in ds.Tables[0].Rows) 
{ 
    Foo.GetValueOrCreateDefault(dr["Key"]).Add(dr["Value"].ToString()) 
} 

शायद तुम यहां तक ​​कि पूरी initialisation के लिए एक विस्तार विधि लिख सकते हैं: GetValueOrCreateDefault() या कुछ है कि जैसे -

+0

क्या थोड़े बात आप के लिए यह संरचना उपयोगी पाते हैं? एक बिल्कुल नया प्रोग्रामर होने के नाते मुझे लगता है कि मैंने अभी तक शब्दकोश संरचना का उपयोग इतना नहीं किया है! – RYFN

+0

फ्रेमवर्क संस्करण जानकारी उपयोगी होगी, LINQ इसे बहुत क्लीनर बना सकता है – AnthonyWJones

+0

@ एंथनी: दरअसल। संपादित टैग .net3.5 – Brann

उत्तर

7

आप एक विस्तार विधि लिख सकता है?

+0

अच्छा समाधान, लेकिन मैं आगे बढ़ूंगा और एक विस्तार विधि शब्दकोश बनाउंगा।AddPair (TKey, TValue)। अगर किसी और को कोड को देखना है तो इसे पढ़ने और समझना बहुत आसान होगा। –

2

मुझे लगता है कि निम्नलिखित करना चाहिए:

class DictionaryOfList : Dictionary<string, List<string>> {} 
  • संपादित मैं और अधिक ठीक से पढ़ना चाहिए। यह सवाल का जवाब नहीं देता है। तनासियस ने इसे हल करने के लिए एक साफ तरीका प्रदान किया है।
+0

धन्यवाद, यह आसान है! – Nick

4

सूची का एक शब्दकोश ... .NET 3.5 में यह ILookup<TKey,TValue> होगा। डिफ़ॉल्ट कार्यान्वयन (Lookup<TKey,TValue>) अपरिवर्तनीय है, लेकिन मैंने MiscUtil के लिए EditableLookup<TKey,TValue> लिखा था। यह उपयोग करने के लिए बहुत आसान हो जाएगा - कि तुलना में यानी

var data = new EditableLookup<string, int>(); 
data.Add("abc",123); 
data.Add("def",456); 
data.Add("abc",789); 

foreach(int i in data["abc"]) { 
    Console.WriteLine(i); // 123 & 789 
} 

अन्य, एक विस्तार विधि:

public static void Add<TKey, TList, TValue>(
    this IDictionary<TKey, TList> lookup, 
    TKey key, TValue value) 
    where TList : class, ICollection<TValue>, new() 
{ 
    TList list; 
    if (!lookup.TryGetValue(key, out list)) 
    { 
     lookup.Add(key, list = new TList()); 
    } 
    list.Add(value); 
} 

static void Main() { 
    var data = new Dictionary<string, List<string>>(); 
    data.Add("abc", "def"); 
} 
+0

अच्छा! मैं <4 विस्तार विधियां। –

+0

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

1

System.Data.DataSetExtensions के लिए एक संदर्भ जोड़ें और आप Linq एक्सटेंशन का उपयोग कर सकते हैं:

var dictOfLst = ds.Tables[0].Rows. 
    //group by the key field 
    GroupBy(dr => dr.Field<string>("key")). 
    ToDictionary(
     grp => grp.Key, 
     //convert the collection of rows into values 
     grp => grp.Select(dr => dr.Field<string>("value")).ToList()); 

मुझे यकीन है कि मैं किसी अन्य वर्ग से परेशान था नहीं कर रहा हूँ, लेकिन एक उपयोगिता या विस्तार विधि इस सरल बना सकता है:

public static Dictionary<TKey, List<TValue>> ToGroupedDictionary<TKey, List<TValue>>(
    this DataTable input, 
    Func<TKey, DataRow> keyConverter, 
    Func<TValue, DataRow> valueConverter) 
{ 
    return input.Rows. 
     //group by the key field 
     GroupBy(keyConverter). 
     ToDictionary(
      grp => grp.Key, 
      //convert the collection of rows into values 
      grp => grp.Select(valueConverter).ToList()); 
} 

//now you have a simpler syntax 
var dictOfLst = ds.Tables[0].ToGroupedDictionary(
    dr => dr.Field<string>("key"), 
    dr => dr.Field<string>("value")); 
+1

क्या आप ToLookup देखते हैं? –

0

the using directive मत भूलना।

यह सीधे उत्तरदायी नहीं है, लेकिन वैसे भी सहायक हो सकता है। जेनेरिक संग्रह प्रकार के लिए "उपनाम का उपयोग करना" आपके कोड को आंखों पर आसान बना सकता है।

using StoreBox = System.Collections.Generic.Dictionary<string, System.Collections.Generic.List<string>>; 
using ListOfStrings = System.Collections.Generic.List<string>; 
class Program 
{ 
    static void Main(string[] args) 
    { 
     var b = new StoreBox(); 
     b.Add("Red", new ListOfStrings {"Rosso", "red" }); 
     b.Add("Green", new ListOfStrings {"Verde", "green" }); 
    } 
} 

इस संकेत के लिए Credit to SO

0

क्यों नहीं बस थोड़ी आसान बनाने:

foreach (DataRow dr in ds.Tables[0].Rows) 
{ 
    string key = dr["Key"].ToString(); 
    if (!Foo.ContainsKey(key)) Foo.Add(key, new List<string>()); 
    Foo[key].Add(dr["Value"].ToString()); 
} 
+0

ऐसा करने का एक कारण यह नहीं है कि जटिलता ओ (एन) के बजाय ओ (2 एन) होगी। बेशक ज्यादातर मामलों में, शायद यह वास्तव में एक मुद्दा नहीं है। – Brann

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

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