Reputation: 9297
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
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
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
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