【问题标题】:How does the .All(db1 => db1.Text != wb.Text)) in LINQ work when comparing two lists?比较两个列表时,LINQ 中的 .All(db1 => db1.Text != wb.Text)) 是如何工作的?
【发布时间】:2016-06-04 16:13:47
【问题描述】:

我最近问了这个问题,关于如何比较两个列表并检查新列表中添加的项目。

我有两个 IList 类型的对象:

public class SampleSentence
{
    public int SampleSentenceId { get; set; } 
    public string Text { get; set; } 
}

IList<SampleSentence> Old = 
   [new SampleSentence() { SampleSentenceId = 1; Text = 'cat' }]

IList<SampleSentence> New = 
   [new SampleSentence() { Text = 'cat' }],
    new SampleSentence() { Text = 'dog' }]

我需要得到的是:

IList<SampleSentence> whatINeed = 
   [new SampleSentence() { Text = 'dog' }]
  • Object Old 是一个 SampleSentences 列表,其中填充了 SampleSentenceId 和 Text 字段。
  • Object New 是一个 SampleSentences 列表,其中仅填充了 Text 字段。它将具有与对象 Old 相同或更多的行

使用 LINQ 如何比较 OldNew 对象(将它们与 Text 的内容链接)并创建另一个 IList,该列表中有名为 New 的附加列?

1. 我收到的答案似乎有效:

IList<SampleSentence> whatINeed = New.GroupJoin(Old,
    newElement => newElement.Text, oldElement => oldElement.Text,
    (newElement, oldElements) => new { newElement, oldElements })
.Where(match => !match.oldElements.Any())
.Select(match => match.newElement)
.ToList();

2. 但我自己也想出了这个答案。

var addS = sampleSentences
              .Where(wb => oldObjS
              .All(db1 => db1.Text != wb.Text))
              .ToList();

这第二个答案似乎也有效,但我不知道为什么。有人可以解释这两种编码方法是否相同并解释 .ALL 在这种情况下如何工作?谁能看到第二种方法在所有情况下都不起作用的原因?

【问题讨论】:

标签: c# linq


【解决方案1】:

它们在功能上是等效的。

为了理解原因,您需要了解AllAny 扩展方法可以互换

All(condition) == !Any(!condition)

所以您的查询 #2 标准

Where(wb => oldObjS.All(db1 => db1.Text != wb.Text))

等价于

Where(wb => !oldObjS.Any(db1 => db1.Text == wb.Text))

或以不同的方式显示它

Where(wb => !oldObjS.Where(db1 => db1.Text == wb.Text).Any())

如果我们构成(只是人为的,下面不是一个有效的构造)

match = oldObjS.Where(db1 => db1.Text == wb.Text)
Where(wb => !match.Any())

然后如您所见,我们得到了查询 #1。

区别在于如何进行匹配,因此表现。基于连接的查询使用基于哈希的实现来执行匹配,因此它具有 O(N + M) 时间复杂度,而第二个查询必须从第一个集合的每个元素执行线性搜索,因此具有 O(N * M) 时间复杂度,其中 NNew.CountMOld.Count

当然,上述内容仅适用于 LINQ to Objects,对于针对真正的 IQueryable 提供程序的 LINQ 查询而言并不那么重要,因为它们可以分析表达式树并将两种变体实际转换为同一个 SQL 查询,甚至他们不这样做,那么数据库 SQL 优化器也可以这样做。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-11-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多