代码之家  ›  专栏  ›  技术社区  ›  Iofacture

属性不相等的两个列表的linq比较

  •  1
  • Iofacture  · 技术社区  · 5 年前

    我看过几篇关于这个的文章( this 尤其是) 因为某些原因我的情况不同。我使用了tony the lion的答案,试图获得具有不同属性值的对象列表,但没有成功。然而,这确实有效:

    List<Task> changedTasksWorking = new List<Task>();
    for (int x = 0; x < originalTaskList.Count; x++)
    {
        if (originalTaskList[x].ActiveFlag != newTaskList[x].ActiveFlag)
        {
            changedTasksWorking.Add(newTaskList[x]);
        }
    }
    

    以下是我认为可以给我同样的结果。但是如果返回的列表应该等于1,那么它就等于0。当我将属性比较翻到 != 去掉内部列表中的nor条件,我得到列表中的所有对象:

    List<Task> notWork = oL.Where(o => newL.Any(n => o.ActiveFlag != n.ActiveFlag)).ToList();
    

    我觉得我在吃疯狂的药。看看上面的一行字,它应该能给我我想要的东西。也许我误解了linq方法 Where Any 相互影响。

    2 回复  |  直到 5 年前
        1
  •  4
  •   Peter Duniho    5 年前

    你提出的linq方法与你看起来实际要做的完全不同。特别是,根据您的原始示例,您有两个完全同步的列表。也就是说,它们具有相同数量的元素,并且一个列表中的每个元素与另一个列表中处于相同位置的相同元素完全对应。

    另一方面,linq代码一次查看一个列表中的每个元素,对于其中的每个元素,在另一个列表中搜索一个属性值不匹配的元素。换句话说,如果 newL 列表包含所有可能值的元素 ActiveFlag 当然它会返回 oL ,因为对于中的每个元素 奥尔 ,linq能够在 纽尔 其中属性值不匹配。

    使用linq至少有几个明显的替代方法 实际工作:

    1. 使用过载 Where() 将索引传递给谓词委托的:
    List<Task> changedTasks = newTaskList
        .Where((n, i) => n.ActiveFlag != originalTaskList[i].ActiveFlag).ToList();
    
    1. 使用 Enumerable.Zip() 将元素按新序列配对并筛选:
    List<Task> changedTasks = originalTaskList
        .Zip(newTaskList, (o, n) => o.ActiveFlag != n.ActiveFlag ? n : null)
        .Where(n => n != null).ToList();
    

    这两种方法都可以。