使用LINQ将两个类合并成一个字典

4
我有两个类,它们共享两个公共属性:Id和Information。
public class Foo
{
     public Guid Id { get; set; }

     public string Information { get; set; }

     ...
}
public class Bar
{
     public Guid Id { get; set; }

     public string Information { get; set; }

     ...
}

使用LINQ,我如何将填充的Foo对象列表和填充的Bar对象列表结合起来:
var list1 = new List<Foo>();
var list2 = new List<Bar>();

将每个Id和Information合并成一个字典:

var finalList = new Dictionary<Guid, string>();

谢谢你提前的支持。

如果有两个具有相同ID但信息不同的项目,您希望发生什么? - Erik Philips
@ErikPhilips 这种情况不会发生,所以我不需要处理它。 - Jonathan
请在此处查看解决方案:https://dev59.com/SG855IYBdhLWcg3w_5qm - Mitja Bonca
既然您有共同的属性,它们是否应该从基类继承,或者因为它们是属性而实现接口呢? - Brad Semrad
2个回答

8
听起来您需要做以下事情:
// Project both lists (lazily) to a common anonymous type
var anon1 = list1.Select(foo => new { foo.Id, foo.Information });
var anon2 = list2.Select(bar => new { bar.Id, bar.Information });

var map = anon1.Concat(anon2).ToDictionary(x => x.Id, x => x.Information);

(您可以在一条语句中完成所有操作,但我认为这种方式更清晰。)

一如既往地准确,Jon。谢谢你。 - Jonathan

0
   var finalList = list1.ToDictionary(x => x.Id, y => y.Information)
            .Union(list2.ToDictionary(x => x.Id, y => y.Information))
                        .ToDictionary(x => x.Key, y => y.Value);

确保ID是唯一的。如果不是,它们将被第一个字典覆盖。

编辑:添加.ToDictionary(x => x.Key, y => y.Value);


2
是的,它可以工作 - 但在我看来似乎有点浪费。为什么要构建三个字典并通过集合操作进行处理,当您只需连接并使用单个ToDictionary调用即可呢? - Jon Skeet
我猜我不知道创建两个匿名列表比创建两个字典更昂贵多少,或者使用 .Concat() 比 .Union() 更具性能优势 举起白旗 - The Internet
内存而言,我认为我的方法是胜者。它不需要构建任何中间集合。与Union相比,Concat非常简单,后者必须为“已返回”的值构建一个集合。另外两个ToDictionary调用还需要大量的哈希和潜在的相等性检查。直接使用类似元组的值类型(例如KeyValuePair)而不是使用匿名类型可能会更便宜一些,但更丑陋。我认为我的版本在简洁性方面也获胜 - 你不需要逻辑上构建那些中间字典。 - Jon Skeet

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接