2013-10-09 22 views
-3

说我有两个字典:的毗连两个词典,使原来的共享密钥更新

Dictionary<string, string> orig = new Dictionary <string, string>(); 
orig.Add("one", "value one"); 
orig.Add("two", ""); 
orig.Add("three", ""); 

Dictionary<string, string> newDict = new Dictionary <string, string>(); 
newDict.Add("one", "this value should not be added"); 
newDict.Add("two", "value two"); 
newDict.Add("three", "value three"); 

我该如何合并两个库,这样所产生的字典更新密钥只有在其对应的值是空的?此外,合并不应添加new中的任何密钥,但不会添加在orig中。也就是说,“one”仍然具有“value one”的值,而“two”和“three”则更新为new的值。

我试着用orig.Concat(new);,但给我留下原来的字典。也许这可以用LINQ来完成?

+0

这不能用LINQ来完成。 – SLaks

+0

@SLaks你介意阐述吗? – tnw

+0

LINQ是关于_queries_;它不能改变现有的对象。 – SLaks

回答

6

尝试:

orig = orig.Keys.ToDictionary(c => c, c=>(orig[c] == "" ? newDict[c] : orig[c])); 
+2

这也应该检查以确保密钥存在于第二个字典中。 – Servy

+2

@Servy,你是对的,但我从OP给出的例子中推断出这两个词典具有匹配的关键集合。我推理的原因是orig字典中存在空字符串值。如果有可能两个字典没有匹配的密钥集合,请这么说,我将修改我的答案代码。 –

+0

@BolucPapuccuoglu一个正确的推论,所以这适合我的具体用例。然而,Servy会是正确的,以获得更广泛的解决方案。非常感谢你! – tnw

1

我想,当他们有助于澄清意图使用foreach

foreach (var pair in orig.Where(x=> string.IsNullOrEmpty(x.Value)).ToArray()) 
{ 
    orig[pair.Key] = newone[pair.Key]; 
} 
1

扩展方法“单行”是伟大的,但这样的事情,我会倾向于用一个明确的循环写一个小方法来完成所需的操作。我认为这是比使用各种扩展方法转换创建一个新的字典更清洁:

public void PopulateMissingValues(Dictionary<string, string> orig, Dictionary<string, string> newDict) 
    { 
     foreach (var pair in orig.Where(p => p.Value == string.Empty)) 
     { 
      string newValue; 
      if (newDict.TryGetValue(pair.Key, out newValue)) 
       orig[pair.Key] = newValue; 
     } 
    } 
2

这个循环,你想要做有效的东西和可读性:

Dictionary<string, string> result = new Dictionary<string, string>(); 
foreach (var keyVal in orig) 
{ 
    if (!string.IsNullOrEmpty(keyVal.Value)) 
     result.Add(keyVal.Key, keyVal.Value); 
    else 
    { 
     string val2; 
     if (newDict.TryGetValue(keyVal.Key, out val2)) 
      result.Add(keyVal.Key, val2); 
     else 
      result.Add(keyVal.Key, ""); 
    } 
} 

结果:

one, value one 
two, value two 
three, value three