【问题标题】:Check if one list contains any elements from another检查一个列表是否包含来自另一个列表的任何元素
【发布时间】:2012-11-09 19:19:05
【问题描述】:

如果一个列表包含来自 list2 的任何名称/值,我只是想返回 true:

这将是我的结构:

public class TStockFilterAttributes
{
    public String Name { get; set; }
    public String Value { get; set; }
}

List<TStockFilterAttributes> List1 = new List<TStockFilterAttributes>();
List<TStockFilterAttributes> List2 = new List<TStockFilterAttributes>();

这应该返回 true:

List1.Add(new TStockFilterAttributes { Name = "Foo", Value = "Bar" });
List2.Add(new TStockFilterAttributes { Name = "Foo", Value = "Bar" });

但这会返回 false,因为 Name && Value 不匹配:

List1.Add(new TStockFilterAttributes { Name = "Foo", Value = "Bar" });
List2.Add(new TStockFilterAttributes { Name = "Foo", Value = "Foo" });

每个列表可以包含许多不同的值,我只需要知道 List1 中的任何一个是否与 List2 中的任何一个匹配。

我尝试过使用:

return List1.Intersect(List2).Any();

但这似乎在所有情况下都返回 false,我假设这是因为我在 List 中持有一个类而不是简单的 int / string?

【问题讨论】:

标签: c# linq


【解决方案1】:

为您的班级覆盖 EqualsGetHashCode 实现:

public class TStockFilterAttributes
{
    public String Name { get; set; }
    public String Value { get; set; }

    public override bool Equals(object obj)
    {
        TStockFilterAttributes other = obj as TStockFilterAttributes;
        if (obj == null)
            return false;

        return Name == obj.Name && Value == obj.Value;
    }

    public override int GetHashCode()
    {
        return Name.GetHashCode() ^ Value.GetHashCode();
    }
}

或者提供Intersect函数的比较器。

【讨论】:

  • 我在这里发布问题后尝试了这个并且它有效。当我被允许时,我会将其标记为答案,因为它与我的解决方案相同。谢谢。
  • @webnoob 欢迎您。问题在于默认的EqualsGetHashCode 实现,它们使用对象引用来比较不同的对象。而 Linq 使用这些方法进行比较。
【解决方案2】:

假设性能无关紧要:

List1.Any(l1 => List2.Any(l2 => l1.Key == l2.Key && l1.Value == l2.Value));

替代方案是覆盖 Equals 或使其成为 Struct(可能不合适)

【讨论】:

    【解决方案3】:
    var query = List1.Where(x => List2.Exists(y => y.Name == x.Name && y.Value == x.Value));
    

    但性能可能很差

    【讨论】:

      【解决方案4】:

      这里的问题是你在比较引用而不是对象。由于您每次都创建一个新对象,因此列表永远不会包含相同的引用。

      试试:

      var FooBar = new TStockFilterAttributes { Name = "Foo", Value = "Bar" };
      var FooFoo = new TStockFilterAttributes { Name = "Foo", Value = "Foo" };
      List1.Add(FooBar);
      List2.Add(FooBar);
      List2.Add(FooFoo);
      return List1.Intersect(List2);
      

      【讨论】:

      • 这就是我认为的问题所在,我现在已经实现了一个 IEqualityComparer 来对问题进行排序。
      • 当然。根据您的需要,您有两种方法。通常情况下,我们想要检查参考资料,但有时您只需要比较这些值。
      【解决方案5】:

      迟到了,但有了 intersect,我们可以使用 select 并避免使用相等。

      list1.Select(Function(p) p.ItemID).Intersect(list2.Select(Function(p)p.ItemID)).Any()
      

      【讨论】:

        猜你喜欢
        • 2012-08-01
        • 1970-01-01
        • 2021-03-02
        • 2022-11-14
        • 1970-01-01
        • 2021-04-14
        • 1970-01-01
        • 2022-12-31
        • 1970-01-01
        相关资源
        最近更新 更多