【问题标题】:Get objects which are in both lists based on specific comparator [duplicate]根据特定比较器获取两个列表中的对象[重复]
【发布时间】:2017-05-06 22:33:48
【问题描述】:

我有两个 List 对象,listAlistB,其中包含 User 对象的集合。

每个User 对象都有一个属性ID

我想根据ID 属性获取listAlistB 中存在的用户列表。

到目前为止,这是我的代码:

listA.Where(a => listB.Any(b => b.ID == a.ID));

有没有更好的方法来做到这一点?感觉它可能效率低下,特别是如果listB 很大。

User 对象没有实现IEquatable

【问题讨论】:

  • ID 是否唯一?也许可以使用 HashSet 代替 ID 作为键。
  • ID 是唯一的 Guid 对象。如果两个User 对象具有相同的ID,那么它们是相同的(但不能直接相等)。
  • 然后创建两个以 ID 为键的 HashSet,使用您显示的方法但比较键。或者正如其他人指出的那样,Intersect() 可能会更好。尚未对此进行测试,因此仅发表评论。
  • @CodeCaster 我的对象没有实现IEquatable。这不是您的链接问题的重复。
  • 然后创建一个新的IEqualityComparer<User> 并将其传递给Intersect()。同一个问题的那个变体也被问了足够多的时间。另见Using LINQ to objects Intersect and Except on a specific property,

标签: c# .net linq


【解决方案1】:

如果User实现IEquatable<User>,假设ID相同,则两个User相同,则可以使用LINQIntersect。例如:

listA.Intersect(listB);

如果User 没有实现IEquatable<User>,您可以使用IEqualityComparer<User> 调用Intersect。例如:

listA.Intersect(listB, new UserEqualityComparer());

在哪里

UserEqualityComparer : IEquatable<User> {...}

【讨论】:

  • User 没有实现 IEquatable&lt;User&gt;
【解决方案2】:

另一个选项是 Join 两个集合的 Id 属性..

var results = listA.Join(listB, a => a.Id, b=> b.Id, (a, b) => a);

【讨论】:

    【解决方案3】:

    应该这样做:

    var result = listA.Intersect(listB);
    

    假设您的 User 类实现了 IEquatable&lt;User&gt;

    如果这不是您的情况,那么您可以执行类似的操作,以便根据 ID 值将两个列表相交:

    var result = listA.Select(s1 => s1.ID).ToList().Intersect(listB.Select(s2 => s2.ID).ToList()).ToList();
    

    这是在两个列表中创建两个新的 ID 值列表,并获取它们之间的交集。

    【讨论】:

    • User 必须实现IEquatable&lt;User&gt;,否则如果用户是不同的实例,这将不起作用。
    • @Lepijohnny:是的,正确,我会解决这个问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-07-29
    • 2021-05-26
    • 2019-11-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-10
    相关资源
    最近更新 更多