【问题标题】:Exclude items of one list in another with different object data types, LINQ?用不同的对象数据类型排除另一个列表中的项目,LINQ?
【发布时间】:2013-10-23 10:59:20
【问题描述】:

我有两个列表,里面填满了他们自己的数据。 假设有两个模型HumanAnotherHuman。每个模型包含不同的字段,但是它们有一些共同的字段,例如LastName, FirstName, Birthday, PersonalID

List<Human> humans = _unitOfWork.GetHumans();
List<AnotherHuman> anotherHumans = _unitofWork.GetAnotherHumans();

我想从列表anotherHumans 中排除项目,其中LastName, FirstName, Birthday 都等于列表humans 中任何项目的相应字段。

但是,如果anotherHumans 列表中的任何项目具有PersonalID 并且列表humans 中的项目具有相同的PersonalID,那么仅通过此PersonalIDHumanAnotherHuman 进行比较就足够了,否则LastName, FirstName and Birthday

我尝试创建新的重复列表并将其从anotherHumans 中排除:

List<AnotherHuman> duplicates = new List<AnotherHuman>();
foreach(Human human in humans)
{
   AnotherHuman newAnotherHuman = new AnotherHuman();
   newAnotherHuman.LastName = human.LastName;
   newAnotherHuman.Name= human.Name;
   newAnotherHuman.Birthday= human.Birthday;
   duplicates.Add(human) 
}
anotherHumans = anotherHumans.Except(duplicates).ToList();

但是我如何比较两个列表中的PersonalID(如果它存在)(它可以为空)。有什么方法可以摆脱创建 AnotherHuman 的新实例和重复列表并仅使用 LINQ 的方法?

提前致谢!

【问题讨论】:

    标签: c# asp.net-mvc linq list


    【解决方案1】:

    与其创建新对象,不如在 linq 查询中检查属性

    List<Human> humans = _unitOfWork.GetHumans();
    List<AnotherHuman> anotherHumans = _unitofWork.GetAnotherHumans();
    
    // Get all anotherHumans where the record does not exist in humans
    var result = anotherHumans
                   .Where(ah => !humans.Any(h => h.LastName == ah.LastName
                                   && h.Name == ah.Name
                                   && h.Birthday == ah.Birthday
                                   && (!h.PersonalId.HasValue || h.PersonalId == ah.PersonalId)))
                   .ToList();
    

    【讨论】:

    • 对于 anotherHumans 中的每个项目,您都需要迭代 human 集合,因此随着集合大小的增加,其性能会显着下降。
    • 这只会比较具有PersonalID 的项目。我不认为这是被问到的。
    • 还是不太好,因为在PersonalID存在的情况下,不需要检查姓氏、姓名和年龄,对吧?
    • 我已经更新了PersonalID 修复。关于性能,我同意这会随着大型数据集而降低,但我不确定这是操作的问题
    • LastNameNameBirthday 始终处于选中状态。如果 PersonalId 为 null 或 PersonalId 与另一个人匹配,最后一行将返回 true
    【解决方案2】:
    var duplicates = from h in humans
                     from a in anotherHumans
                     where (h.PersonalID == a.PersonalID) ||
                           (h.LastName == a.LastName && 
                            h.FirstName == a.FirstName && 
                            h.Birthday == a.Birthday)
                     select a;
    
    anotherHumans = anotherHumans.Except(duplicates);
    

    【讨论】:

      【解决方案3】:
      var nonIdItems = anotherHumans
         .Where(ah => !ah.PersonalID.HasValue)
         .Join(humans, 
               ah => new{ah.LastName, 
                 ah.FirstName, 
                 ah.Birthday}, 
               h => new{h.LastName, 
                 h.FirstName, 
                 h.Birthday}, 
               (ah,h) => ah);
      var idItems = anotherHumans
         .Where(ah => ah.PersonalID.HasValue)
         .Join(humans, 
               ah => ah.PersonalID
               h => h.PersonalID, 
               (ah,h) => ah);
      var allAnotherHumansWithMatchingHumans = nonIdItems.Concat(idItems);
      var allAnotherHumansWithoutMatchingHumans = 
            anotherHumans.Except(allAnotherHumansWithMatchingHumans);
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-02-16
        相关资源
        最近更新 更多