C# 泛型列表比较并获取不匹配的行



我在C#中有两个列表。我需要一个 LINQ 查询来仅比较和列出不匹配的行。

List<First> firstList;
List<Second> secondList;
both have the unique property called ID;

首页列表:

ID  Desc1   Desc2           
1   aaa     mmm             
2   bbb     fff             
3   ccc     ttt   
4   ddd     yyy
5   eee     ggg

第二列表:

ID  Desc1   Desc2   Status          
1   aaa     mm      P       
2   bbb     fff     S       
3   ccc     ttt     P   
4   ddd     yy      S
5   eee     ggg     P

结果:

ID  Desc1   Desc2   Status
2   aaa     mm      P
4   ddd     yy      S

我想将第一个列表中的 Desc1 和 Desc2 与第二个列表进行比较,并且需要不匹配的项目的状态。

一些查找结果的方法(lambda,linq(:

var query0 = secondList.Where(item => firstList.All(f => !item.Desc1.Equals(f.Desc1)  || !item.Desc2.Equals(f.Desc2)));

var query1 =
    from item in secondList
    where firstList.All(f => !item.Desc1.Equals(f.Desc1) || !item.Desc2.Equals(f.Desc2))
    select item;

如果你想把结果放在一个列表中而不是枚举中,你只需在最后添加 Tolist((:

var list0 = secondlist.Where(item => firstlist.All(f => !item.Desc1.Equals(f.Desc1) || !item.Desc2.Equals(f.Desc2))).ToList();

要在评论中回答您的问题:

如果要迭代或选择特定ID,可以这样做:

        foreach(var item in query0)
        {
           Console.WriteLine($"ID:{item.ID}, Desc1:{item.Desc1}, Desc2:{item.Desc2}, Status:{item.Status}");  
        }
        //if you want to query a particular id:
        var queryid = query0.Where(item => item.ID == particularID);

请参阅下文。您需要在两个列表之间做并集,然后删除交集。您将需要实现IEqualityComparer接口。

void Main()
{
    List<UserProfile> u1 = new List<UserQuery.UserProfile>(){
        new UserProfile(){ID = 1, FirstName  = "Super" , LastName = "Man"},
        new UserProfile(){ID=2, FirstName = "Spider", LastName="Man"},
        new UserProfile(){ID=3, FirstName = "Bat", LastName="Man"}
    };
    List<UserProfile> u2 = new List<UserProfile>(){
        new UserProfile(){ID = 1, FirstName="Super", LastName="Man"},
        new UserProfile(){ID = 2, FirstName="Thor", LastName="Ragnarok"},
        new UserProfile(){ID = 3, FirstName="Hulk", LastName="Baner"}
    };
//  u1.Intersect(u2, new UserProfileComparer())
//      .ToList()
//      .ForEach(x => Console.WriteLine(x.Name));
//  u1.Except(u2, new UserProfileComparer())
//      .ToList()
//      .ForEach(x => Console.WriteLine(x.Name));
    // (u1 + u2) - (u1*u2)
    u1.Union(u2, new UserProfileComparer())
        .Except(u1.Intersect(u2, new UserProfileComparer()))
        .Distinct()
        .ToList()
        .ForEach(x => Console.WriteLine(x.Name));
}
class UserProfile
{
    public int ID {get;set;}
    public string Name => LastName + "," + FirstName;
    public string FirstName {get;set;}
    public string LastName {get;set;}
}
class UserProfileComparer : IEqualityComparer<UserProfile>
{
    public bool Equals(UserProfile item1, UserProfile item2)
    {
        if (object.ReferenceEquals(item1, item2))
            return true;
        if (item1 == null || item2 == null)
            return false;
        return item1.FirstName.Equals(item2.FirstName) &&
               item1.LastName.Equals(item2.LastName);
    }
    public int GetHashCode(UserProfile item)
    {
        return new { item.FirstName, item.LastName }.GetHashCode();
    }
}

我建议不要像其他答案中提到的那样使用 !=,而是使用连接。如果你的列表很大!=会消耗大量的处理时间。

以下代码可能看起来很丑陋,但确实达到了目的并且速度更快。

var unmatchedRec = (from p in lstFiles1
    join f in lstFiles2
    on new
    {
        p.FileName,
        p.PageNumber
    } equals new
    {
        f.FileName,
        f.PageNumber
    } into fg
    from fgi in fg.DefaultIfEmpty()
    select new { p, fgi })
        .Where(t => t.fgi == null)
        .Select(t => t.p)
        .ToList();

相关内容

  • 没有找到相关文章

最新更新