简体   繁体   English

LINQ比较两个列表,其中属性值不相等

[英]LINQ Compare two lists where property value is not equal

I have been over a few StackOverflow articles about this ( this in particular) and for some reason my case is different. 我一直在这个几个StackOverflow的文章( 尤其是),并由于某种原因,我的情况是不同的。 I've used Tony the Lion's answer to attempt to get a list of objects that have different property values, without success. 我已经用狮子托尼的答案来尝试获取具有不同属性值的对象列表,但没有成功。 This, however does work: 但是,这确实有效:

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]);
    }
}

The following is what I thought would provide me the same result. 以下是我认为可以提供相同结果的内容。 But where the returned list should equal 1, it instead equals zero. 但是在返回的列表应该等于1的地方,它等于0。 When I flip the property comparison to != and remove the nor condition on the inner list, I get ALL the objects of the list instead: 当我将属性比较翻转到!=并删除内部列表的nor条件时,我得到了列表的所有对象:

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

I feel like I'm taking crazy pills. 我觉得自己在服用疯药。 Looking at the above one-liner that should give me what I'm asking for. 看看上面的一线,应该可以满足我的要求。 Perhaps I have misunderstood how the LINQ methods Where and Any are interacting. 也许我误解了LINQ方法WhereAny的相互作用。

Your proposed LINQ approach is completely different from what you seem to actually be trying to do. 您提出的LINQ方法与您实际尝试做的完全不同。 In particular, according to your original example, you have two lists that are exactly in sync with each other. 特别是,根据您的原始示例,您有两个彼此完全同步的列表。 Ie they have the same number of elements, and each element from one list corresponds exactly to the same element in the same position in the other list. 也就是说,它们具有相同数量的元素,并且一个列表中的每个元素与另一列表中相同位置的相同元素完全对应。

Your LINQ code, on the other hand, looks at each element in one list at a time, and for each of those elements, searches the other list for one that has a property value that doesn't match. 另一方面,您的LINQ代码一次查看一个列表中的每个元素,然后针对每个这些元素,在另一个列表中搜索属性值不匹配的元素。 In other words, if the newL list has elements of all possible values of ActiveFlag then of course it will return all elements of oL , because for each element in oL , LINQ is able to find an element in newL where the property value doesn't match. 换句话说,如果newL列表具有的所有可能值的元素ActiveFlag那么当然它会返回的所有元素oL ,因为在每一个元素oL ,LINQ是能够找到一个元素newL其中属性值不比赛。

There are at least a couple of obvious alternatives using LINQ that will actually work: 至少有一对夫妇使用LINQ, 实际工作明显的替代品:

  1. Use the overload for Where() that passes the index to the predicate delegate: 将重载用于将索引传递给谓词委托的Where()
List<Task> changedTasks = newTaskList
    .Where((n, i) => n.ActiveFlag != originalTaskList[i].ActiveFlag).ToList();
  1. Use Enumerable.Zip() to pair up elements in a new sequence and filter that: 使用Enumerable.Zip()配对新序列中的元素并过滤以下内容:
List<Task> changedTasks = originalTaskList
    .Zip(newTaskList, (o, n) => o.ActiveFlag != n.ActiveFlag ? n : null)
    .Where(n => n != null).ToList();

Either of those should work fine. 这些都应该工作正常。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM