Словарь слияния - PullRequest
       7

Словарь слияния

0 голосов
/ 22 декабря 2009

У меня есть словарь словарей:

SortedDictionary<int,SortedDictionary<string,List<string>>>

Я хотел бы объединить два словаря, например, key = 2 и key = 3.

Очень важно, чтобы у меня могли быть дубликаты ключей в соответствующих словарях.

пример ключа = 2 имеет словарь Ключ, Значение "1000",{a,b,c}
и ключ = 3 имеет ключ словаря, значение "1000",{z}.

Итак, я хотел бы объединить ключ 2 и ключ 3, и в результате получился бы следующий отсортированный словарь, значение "1000",{a,b,c,z}.

Я новичок в синтаксисе LINQ, так что вы могли бы помочь решить эту проблему с помощью подробного кода ..

Спасибо

Ответы [ 2 ]

2 голосов
/ 22 декабря 2009

Это не проблема LINQ. Вот общая версия, которая решит вашу проблему.

static class SortedDictionaryExtensions {
    public static void MergeKeys<TKey1, TKey2, TValue>(
        this SortedDictionary<TKey1, SortedDictionary<TKey2, List<TValue>>> dictionary,
        TKey1 intoKey,
        TKey1 fromKey
    ) {
        if (dictionary == null) {
            throw new ArgumentNullException("dictionary");
        }
        if (intoKey == null) {
            throw new ArgumentNullException("intoKey");
        }
        if (fromKey == null) {
            throw new ArgumentNullException("fromKey");
        }

        SortedDictionary<TKey2, List<TValue>> to;
        SortedDictionary<TKey2, List<TValue>> from;
        if (!dictionary.TryGetValue(intoKey, out to)) {
            throw new ArgumentOutOfRangeException("intoKey");
        }
        if (!dictionary.TryGetValue(fromKey, out from)) {
            throw new ArgumentOutOfRangeException("fromKey");
        }
        foreach(TKey2 key in from.Keys) {
            if (to.Keys.Contains(key)) {
                to[key].AddRange(from[key]);
            }
            else {
                to.Add(key, from[key]);
            }
        }
        dictionary.Remove(fromKey);
    }
}

Использование:

 SortedDictionary<int, SortedDictionary<string, List<string>>> list = 
     new SortedDictionary<int, SortedDictionary<string, List<string>>>();
 list.Add(2, new SortedDictionary<string, List<string>>());
 list[2].Add("1000", new List<string>() { "a", "b", "c" });
 list[2].Add("2000", new List<string>() { "b", "c" });
 list.Add(4, new SortedDictionary<string, List<string>>());
 list[4].Add("1000", new List<string>() { "z" });
 list[4].Add("3000", new List<string>() { "y" });

 list.MergeKeys(2, 4);

Вот как вы подходите к такой проблеме. Сначала укажите, что вы пытаетесь сделать.

Учитывая SortedDictionary<TKey1, SortedDictionary<TKey2, List<TValue>>> и два ключа intoKey и fromKey в словаре, объединить словарь с ключом fromKey в словарь с ключом intoKey.

Теперь укажите, что означает объединение двух словарей. Для двух словарей to и from типа SortedDictionary<TKey2, List<TValue>> объединить их означает следующее. Для каждого TKey2 key в from есть две возможности:

  1. key в to. В этом случае добавьте список from[key] в список to[key].
  2. key не в to. В этом случае добавьте key к to со значением from[key].

Затем удалите ключ fromKey из словаря.

Давайте переведем это в код:

Учитывая SortedDictionary<TKey1, SortedDictionary<TKey2, List<TValue>>> и две клавиши intoKey и fromKey в словаре

SortedDictionary<TKey2, List<TValue>> to;
SortedDictionary<TKey2, List<TValue>> from;
// check that dictionary has intoKey
if (!dictionary.TryGetValue(intoKey, out to)) {
    throw new ArgumentOutOfRangeException("intoKey");
}
// check that dictionary has fromKey
if (!dictionary.TryGetValue(fromKey, out from)) { 
     throw new ArgumentOutOfRangeException("fromKey");
}

Для каждого TKey2 key в from есть две возможности:

foreach(TKey2 key in from.Keys) {
     // key is in to
     if (to.Keys.Contains(key)) {
          // add the list from[key] to the list to[key]
          to[key].AddRange(from[key]); 
     }
     // key is not in to
     else { 
          // add an entry (key, from[key]) to the dictionary
          to.Add(key, from[key]); 
     }
 }

Затем удалите ключ fromKey из словаря.

dictionary.Remove(fromKey);

Остальная часть кода просто проверка ошибок

1 голос
/ 22 декабря 2009

LINQ здесь не сильно поможет.

Вам следует перебрать каждую KeyValuePair во втором словаре, вызвать TryGetValue, чтобы найти соответствующий под-словарь для ключа в первом словаре (если его там нет, добавьте его), затем повторите процесс для под-словаря словарь и, наконец, добавьте все элементы в списке из второго словаря в соответствующий список в первом словаре.

Вы должны быть в состоянии преобразовать это в C # относительно легко; мы не будем писать весь ваш код для вас.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...