使用Dictionary <string,string =“”>中的相同键连接值

时间:2017-12-12 08:22:33

标签: c# dictionary

我需要结合2个词典。它们具有相同的键( KKK ),具有不同的值:

Dictionary<string, string> dic1 = ...Load***();
Dictionary<string, string> dic2 = ...Load***();

DIC1:

...
[29] {[RCP, 555501001]}
[30] {[KKK, 04611105012042000120]}
...

DIC2:

...
[49] {[SUM, 85737]}
[50] {[KKK, 04611701040040000180]}
...

联:

Dictionary<string, string> dicUnion= dic1.Union(dic2).OrderBy(k => k.Key).ToDictionary(kvp => kvp.Key, kvp => kvp.Value);

结果:

ThrowArgumentException: The item with the same key has already been added.

我在联合字典

中使用相同的键连接值
...
[29] {[RCP, "555501001"]}
[30] {[KKK, "04611105012042000120 04611701040040000180"]}
[31] {[SUM, "85737"]}
...

4 个答案:

答案 0 :(得分:4)

我会使用一个简单的循环来添加/追加项目

Dictionary<string, string> dicUnion = new Dictionary<string, string>(dic1); 
foreach(var item in dic2)
{
    if(dicUnion.ContainsKey(item.Key))
    {
        dicUnion[item.Key] += " " + item.Value;
    }
    else
    {
        dicUnion.Add(item.Key, item.Value);
    }
}

答案 1 :(得分:4)

如果你真的想在这种情况下使用LINQ(我更喜欢循环):

var dicUnion = dic1.Concat(dic2)
    .GroupBy(kv => kv.Key)
    .ToDictionary(g => g.Key, g => String.Join(" ", g.Select(kv => kv.Value)));

这将合并两个词典,但不关心常用键或不同的值。

  

我需要结合2个字典,它们具有相同的密钥(KKK)   不同的价值

好的,如果你只想创建一个公共密钥字典:

var union = from kv1 in dic1
            join kv2 in dic2
            on kv1.Key equals kv2.Key into keyGroup
            where keyGroup.Any()
            select new KeyValuePair<string, string>(kv1.Key, string.Join(" ", keyGroup.Select(kv => kv.Value)));

Dictionary<string, string> dicUnion = union.ToDictionary(kv => kv.Key, kv => kv.Value);

但是,不是在两个词典中连接具有相同键的值,而是使用不同的方法。使用Lookup<TKey, TValue>。例如:

var keyLookup = dic1.Concat(dic2).ToLookup(kv => kv.Key, kv => kv.Value);

现在你可以用值f.e.做你想要的wahtever。创建一个List<string>

List<string> values = keyLookup["KKK"].ToList();

答案 2 :(得分:1)

试试这个;

        var intersectedItems = dic1.Where(x => dic2.ContainsKey(x.Key)).Select(x => new
        {
            Key = x.Key,
            Value = x.Value + " " + dic2[x.Key]
        }).ToDictionary(kvp => kvp.Key, kvp => kvp.Value);
        var dicUnion = dic1.Where(x => !intersectedItems.ContainsKey(x.Key))
            .Union(dic2.Where(x => !intersectedItems.ContainsKey(x.Key)))
            .Union(intersectedItems).OrderBy(k => k.Key)
            .ToDictionary(kvp => kvp.Key, kvp => kvp.Value);

答案 3 :(得分:0)

如果您想使用相同的密钥连接ONLY值,可以使用IEnumerable.Join方法,如下所示:

var res = dic1.Join(dic2, o1 => o1.Key, o2 => o2.Key, (o1, o2) => new { o1.Key, Value1 = o1.Value, Value2 = o2.Value});

参数是第二个IEnumerable,键选择器和结果选择器。在我的代码片段中,我创建了一个匿名类,但您可以创建所需的任何结构。结果再次为IEnumerable,您可以迭代或使用其ToList()ToArray()等方法。

编辑:在阅读其他帖子的评论后,我知道你想得到这样的东西:

dic1.Concat(dic2)
    .ToLookup(o => o.Key, o => o.Value)
    .ToDictionary(o => o.Key, o => string.Join(" ", o.Distinct()))