Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/tensorflow/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 通过合并两个列表并删除重复项来创建字典是否有一个线性LINQ构造_C#_Linq - Fatal编程技术网

C# 通过合并两个列表并删除重复项来创建字典是否有一个线性LINQ构造

C# 通过合并两个列表并删除重复项来创建字典是否有一个线性LINQ构造,c#,linq,C#,Linq,我有两个类,每个类有两个集合: public class ClassA { String key; String value; // Some other fields specific to ClassA } public class ClassB { String key; String value; // Some other fields specific to ClassB } List<ClassA> listA; Li

我有两个类,每个类有两个集合:

public class ClassA {
    String key;
    String value;
    // Some other fields specific to ClassA
}

public class ClassB {
    String key;
    String value;
    // Some other fields specific to ClassB
}

List<ClassA> listA;
List<ClassB> listB;
公共类ClassA{
字符串键;
字符串值;
//某些特定于ClassA的其他字段
}
公共B类{
字符串键;
字符串值;
//某些特定于ClassB的其他字段
}
清单a;
名单b;
我想从
key
value
from
listA
listB
构建
Dictionary
,如果两个列表都包含具有相同
key
但不同
value
的对象,那么
value
将从
listB
生成

现在,我有了一个解决方案-从
listA
创建
dictionaryA
,从
listB
创建
dictionaryB
,通过正确处理重复项来合并这些词典。有几个SO帖子解释了如何做到这一点

我的问题有点学术性-是否有一个线性LINQ构造可以完成我想做的事情?

这里有一种方法:

 var merged =
     listA.Select(b => new { key = b.key, val = b.value })
     .Union(listB.Select(b => new { key = b.key, val = b.value }))
     .ToDictionary(m => m.key, n => n.val);;
请注意,这不会处理具有相同键但不同值的对象

要处理重复项,您需要:

 var d = listA.Select(b => new { key = b.key, val = b.value })
              .Union(listB.Select(b => new { key = b.key, val = b.value }))
              .GroupBy(x => x.key)
              .Select(x => x.First())
              .ToDictionary(m => m.key, n => n.val);
请注意,这只保留具有给定键的第一条记录和具有相同键的记录,但不同的值会丢失


测试代码

public static void Main(string[] args)
{
    List<ClassA> listA = new List<ClassA>() { 
        new ClassA() { key = "A", value = "1" }, 
        new ClassA() { key = "B", value = "2" }};
    List<ClassB> listB = new List<ClassB>() { 
        new ClassB() { key = "B", value = "2" }, 
        new ClassB() { key = "C", value = "3" }, 
        new ClassB() { key = "A", value = "4" }};

    var d = (...)

    foreach( var kvp in d ) {
        Console.WriteLine($"{kvp.Key}: {kvp.Value} ");
    }
}

listA.Zip(listB,(a,b)=>newkeyvaluepair(a,b)).Distinct().ToDictionary(x=>x.Key)
我看不出
Zip
对手头的问题有什么作用;因为您将得到两个类的KeyValuePairs,这两个类实际上已经是KVP本身了。@JohnWu:
zip()
如果my
listA
包含键和
listB
包含值,则可以使用。在我的例子中,两个列表本身都包含KVP。使用重复处理的答案看起来最接近于回答问题。有两件事:1)他们指定如果键是重复的,他们需要B的值;因此,他们应该使用
Last()
,而不是
First()
。2) 你可以跳过第二个
Select()
,直接使用
.GroupBy(x=>x.key).ToDictionary(g=>g.key,g=>g.Last().val)
如果我想保留
listB中的值,如果有重复的键,那么我可以(1)使用
Last()
而不是
first()
(如@NPras建议)或(2)在表达式计算
var d
中交换
listB
listA
A: 1
B: 2
C: 3