Nano HE
Nano HE

Reputation: 9297

Question on using List

I created an List like this

List<Dictionary<DicKeyCla, DicValCla>>

public Class DicKeyCla
{
   public EnKey1 DicKeyItem1,
   public EnKey2 DicKeyItem2,
}

public enum EnKey1 
{
   A1,
   A2,
   A3,
   A4,
   A5
}

public enum EnKey2 
{
   B11,
   B12,
   B13,
   B14,
   B15,
   B16,
   B17,
   B18,
   B19,
}

As I know, there is contains() method available for List class.

If I called an function which argues contain the DicKeyCla members like A3 and B15.

How can I pick out the entirely dictionary member from the Top level List rapidly?

I need do more operation on dictionary member.

Upvotes: 0

Views: 90

Answers (3)

Gabe
Gabe

Reputation: 86698

Here's the easy way to do it:

public static Dictionary<DicKeyCla, DicValCla>
     FindDict(List<Dictionary<DicKeyCla, DicValCla>> haystack,
              DicKeyCla needle)
{
    foreach (Dictionary<DicKeyCla, DicValCla> dict in haystack)
        if (dict.ContainsKey(needle))
            return dict;
    return null;
}

Given a list of dictionaries and a key, it will return the first dictionary that has that key, or null if none in the list do.

Or more generically:

public static IDictionary<TKey, TValue>
     FindDict<TKey, TValue>(IEnumerable<IDictionary<TKey, TValue>> haystack,
                            TKey needle)
{
    foreach (IDictionary<TKey, TValue> dict in haystack)
        if (dict.ContainsKey(needle))
            return dict;
    return null;
}

If you need to do this lookup frequently or the list is very long, you may need to index your keys with a Dictionary<DicKeyCla, Dictionary<DicKeyCla, DicValCla>> that holds which dictionary contains which key. If multiple dictionaries can contain the same key then you would need a Dictionary<DicKeyCla, List<Dictionary<DicKeyCla, DicValCla>>> to store your index.

If you already have the list and want to create an index, you could do this:

Dictionary<DicKeyCla, Dictionary<DicKeyCla, DicValCla>> index =
     new Dictionary<DicKeyCla, Dictionary<DicKeyCla, DicValCla>>();
foreach (Dictionary<DicKeyCla, DicValCla> dict in list)
    foreach (KeyValuePair<DicKeyCla, DicValCla> item in dict)
        index[item.Key] = dict;

// or in LINQ
Dictionary<DicKeyCla, Dictionary<DicKeyCla, DicValCla>> index =
    (from dict in list
     from item in dict
     select new { item.Key, dict })
    .ToDictionary(e => e.Key, e => e.dict);

And here's how you'd use the index:

public static Dictionary<DicKeyCla, DicValCla>
     FindDict(Dictionary<DicKeyCla, Dictionary<DicKeyCla, DicValCla>> index,
              DicKeyCla needle)
{
    Dictionary<DicKeyCla, DicValCla> result;
    index.TryGetValue(needle, out result);
    return result;
}

Upvotes: 1

m0sa
m0sa

Reputation: 10940

I have a strange feeling (but I'm probably wrong) that you wrapped your Dictionary with a List hoping you could search the 1 instance of the dictionary with the Contains method and all you want is to access the dictionary members by a combination of EnKey1 and EnKey2. Something like this:

public struct Key // note the struct...
{
    public static Key A(EnKey1 k1, EnKey2 k2)
    {
       Key k = new Key();
       k.Key1 = k1;
       k.Key2 = k2;
       return k;
    }
    public EnKey1 Key1;
    public EnKey2 Key2;
}


Dictionary<Key, string> dic = new Dictionary<Key, string>();
dic.Add(Key.A(EnKey1.A1,EnKey2.B19), "test");
Console.WriteLine(dic[Key.A(EnKey1.A1,EnKey2.B19)]); 
// outputs "test"
// then you can do:
// dic.ContainsKey(Key.A(EnKey1.A1,EnKey2.B19)) -> true
// dic.ContainsKey(Key.A(EnKey1.A2,EnKey2.B19)) -> false

Upvotes: 1

Ran
Ran

Reputation: 6159

The List.Contains method would only check if the parameter you send it is an item in the list.

If you want to be able to find an entire dictionary that contains some given A3 or B15 from this data strcuture, you will have to implement this yourself.

You can do something like manage an internal dictionary that would keep mapping from various A3/B15/etc objects to Lists of Dictionaries to which they have been added.

If O(1) search is not very important to you, consider favoring simplicity over performance, and just scan the list.

Upvotes: 1

Related Questions