【问题标题】:Linq Query Filter from two lists where row differs来自行不同的两个列表的 Linq 查询过滤器
【发布时间】:2018-05-31 08:16:07
【问题描述】:

不确定如何制定此 Linq 查询。 我有两个列表,每个列表都包含 HashCheck 对象:

class HashCheck
{
   public string Id {get; set;}
   public string Hash {get; set;}
}

所以,给定

List<HashCheck> list1;
List<HashCheck> list2;

我需要一个查询,它会生成一个列表,其中包含行的 ID 匹配的行,但哈希不匹配。

例如

List1 =   
{1, 12345,  
 2, 34323,  
 3, 34083,  
 4, 09887}  

List2 =  
{1, 00001,  << matching id, not matching hash  
 2, 34323,  
 3, 11112,  << matching id, not matching hash  
 4, 09887  
 5, 98845}  

ResultList =  
{1, 00001,  
 3, 11112}  

注意:在 List2 中,有一个额外的行,如果它包含在 ResultList 中将是一个奖励。但如果需要,我知道如何在单独的查询中做到这一点。

感谢您的帮助。

【问题讨论】:

    标签: linq


    【解决方案1】:

    试试这个代码:

         var list3 = (from i in list1
                      from j in list2
                      where i.Id == j.Id && i.Hash != j.Hash
                      select new HashCheck() { Id = j.Id, Hash = j.Hash
                      }).ToList<HashCheck>();
    

    您可以使用加入。类似于下面的代码:

          var list3 = (from i in list1
                       join j in list2 on i.Id equals j.Id
                       where i.Hash != j.Hash
                       select new HashCheck() { Id = j.Id, Hash = j.Hash 
                       }).ToList<HashCheck>();
    

    【讨论】:

      【解决方案2】:

      您似乎希望结果包含来自list2HashCheck 对象,这意味着:

      var ans = list2.Where(hc2 => !list1.Any(hc1 => hc1.Id == hc2.Id && hc1.Hash == hc2.Hash));
      

      例如返回所有在IdHash 中匹配的没有list1 元素的list2 元素。

      如果list1(和/或list2)非常大并且需要考虑性能,您可以将list1 转换为Dictionary 并针对它进行查找:

      var list1map = list1.ToDictionary(hc1 => hc1.Id, hc1 => hc1.Hash);
      var ans2 = list2.Where(hc2 => !list1map.TryGetValue(hc2.Id, out var hash1) || hash1 != hc2.Hash);
      

      另一种选择是为您的班级实现Equals/GetHashCode,然后您可以使用LINQ Except

      将以下方法添加到您的类中:

      public override bool Equals(object other) => (other is HashCheck hco) ? Id == hco.Id && Hash == hco.Hash : false;
      public override int GetHashCode() => (Id, Hash).GetHashCode();
      

      现在计算很简单:

      var ans3 = list2.Except(list1);
      

      注意:如果您的 HashCode 对象未被视为不可变对象,那么以这种方式实现 Equals/GetHashCode 可能会出现问题。如果已经存储在其中的对象的哈希码发生更改,某些集合类真的不喜欢它。 此外,最好同时实现 operator==operator!= 并可能实现 IEquatable。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-10-10
        • 2023-04-07
        • 1970-01-01
        • 1970-01-01
        • 2016-06-27
        • 1970-01-01
        • 1970-01-01
        • 2020-12-18
        相关资源
        最近更新 更多