2009-12-21 80 views
0

我有字典的解释:字典合并

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

我想合并两个库例如键= 2和键= 3

非常重要的,我可以有重复键在各自的字典。

例如键= 2具有字典键,值"1000",{a,b,c}
和密钥= 3具有字典键,值"1000",{z}

所以我想合并关键2和关键3,结果将是以下Sorted Dictionary关键字,值"1000",{a,b,c,z}

我与LINQ语法初学者,所以你能帮助详细信息代码解决这个..

感谢

+2

基于粗略的检查,我说有你使用了错误的数据结构,你的工作非常好的变化。首先,虽然您有“1000”,{a,b,c,z}作为您的目标值,但您没有说明目标键应该是什么。此外,将每个值与每个值配对需要线性搜索值集合中的每个项目,使其至少为O(n^2)。有机会,你能描述一下你的问题是什么以及你的字典代表什么样的数据?从那里,有人可能会提出一个更好的数据结构来支持高效的合并。 – Juliet 2009-12-22 00:13:24

+0

这不会是一个线性搜索。 (这是一个_Sorted_Dictionary) – SLaks 2009-12-22 00:14:44

+0

当我看到嵌套字典时,我感到可疑。你有没有想过使用一个组合键,如'SortedDictionary ,List >'?你在用什么?不同的数据结构可能更合适。 – jason 2009-12-22 00:49:40

回答

2

这不是一个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>>>和两个键intoKeyfromKey在字典中,合并与关键fromKey字典与关键intoKey字典。

现在指定合并两个字典的含义。给定两个字典tofrom类型SortedDictionary<TKey2, List<TValue>>合并它们意味着以下内容。对于fromTKey2 key有两个possiblities:

  1. keyto。在这种情况下,将列表from[key]添加到列表to[key]
  2. key不在to。在这种情况下,将key加到to的值为from[key]

然后,从字典中删除键fromKey

让我们把这种代码:

给定一个SortedDictionary<TKey1, SortedDictionary<TKey2, List<TValue>>>和两个键intoKeyfromKey在字典

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

对于fromTKey2 key有两个possiblities:

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

代码的剩下的只是错误检查

+0

非常感谢你杰森 这就是我试图完成 伯纳德 – 2009-12-22 00:58:33

1

LINQ也不会有多大效果在这里。

您应该遍历第二个字典中的每个KeyValuePair,调用TryGetValue为第一个字典中的键找到相应的子字典(如果它不存在,则添加它),然后重复子字典的过程最后,将列表中的所有项目从第二个字典添加到第一个字典中的相应列表。

你应该能够相对容易地将其转换为C#;我们不会为您编写所有的代码。