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
fromlistA
和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()
如果mylistA
包含键和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