Вопрос по использованию Списка - PullRequest
0 голосов
/ 14 декабря 2010

Я создал такой список

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,
}

Как я знаю, для класса List доступен метод contains().

Если бы я вызвал функцию, аргументы которой содержат DicKeyCla членов, таких как A3 и B15.

Как быстро выбрать полностью словарный элемент из списка Верхний уровень ?

Мне нужно сделать больше операций над членом словаря.

Ответы [ 3 ]

1 голос
/ 14 декабря 2010

Вот простой способ сделать это:

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;
}

Учитывая список словарей и ключ, он вернет первый словарь, в котором есть этот ключ, или ноль, если его нет в списке.

Или более обобщенно:

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;
}

Если вам нужно часто выполнять этот поиск или список очень длинный, вам может понадобиться проиндексировать ваши ключи с помощью Dictionary<DicKeyCla, Dictionary<DicKeyCla, DicValCla>>, в котором содержится, какой словарь содержит какой ключ. Если несколько словарей могут содержать один и тот же ключ, то вам понадобится Dictionary<DicKeyCla, List<Dictionary<DicKeyCla, DicValCla>>> для хранения вашего индекса.

Если у вас уже есть список и вы хотите создать индекс, вы можете сделать это:

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);

А вот как вы будете использовать индекс:

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;
}
1 голос
/ 14 декабря 2010

У меня странное ощущение (но я, вероятно, ошибаюсь), что вы завернули свой словарь списком, надеясь, что вы можете найти 1 экземпляр словаря с помощью метода Contains, и все, что вам нужно, - это получить доступ к членам словаря комбинация EnKey1 и EnKey2. Примерно так:

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
1 голос
/ 14 декабря 2010

Метод List.Contains будет только проверять, является ли отправленный вами параметр элементом в списке.

Если вы хотите иметь возможность найти весь словарь, содержащий некоторые данные A3 или B15 из этой строки данных, вам придется реализовать это самостоятельно.

Вы можете сделать что-то вроде управления внутренним словарем, который будет сопоставлять различные объекты A3 / B15 / etc со списками словарей, в которые они были добавлены.

Если поиск O (1) не очень важен для вас, подумайте о том, чтобы отдать предпочтение простоте, а не производительности, и просто отсканируйте список.

...