Linq:Select 和 Where 有啥区别

Posted

技术标签:

【中文标题】Linq:Select 和 Where 有啥区别【英文标题】:Linq: What is the difference between Select and WhereLinq:Select 和 Where 有什么区别 【发布时间】:2010-11-15 19:30:12 【问题描述】:

SelectWhere 方法在 Linq 中可用。每个开发人员都应该了解这两种方法吗?例如:何时使用一种优于另一种,使用一种优于另一种的优势等。

【问题讨论】:

我认为这个问题不应该被标记为CW,它可能有一个确定的答案。 @Brandon 如果是客观的,标记 CW 并没有错。 @Rex,我同意。只是说 Select 和 Where 之间的区别有一个明确的答案,问题的第二部分可能基于普遍接受的做法。我只是指出这一点,以防 OP 不确定将事物标记为 CW。如果他确实打算让它成为 CW,那对我来说很好。 它有很多问题。 CW 是无用的,当人们将问题完全随机标记为 CW 时,情况更是如此 【参考方案1】:
List<string> randomList = new List<string>  "1", "2", "3" ;        
var result = test.Where(value => value == "1");
Console.WriteLine(result.Count());

将产生“1”作为结果,过滤掉后包含对象“1”的那个。

List<string> randomList = new List<string>  "1", "2", "3" ;        
var result = test.Select(value => value == "1");
Console.WriteLine(result.Count());

将产生“3”作为结果,因为它没有过滤,即使条件不匹配,它也会将其选择到“结果”列表中。

结论:Where 检查条件。 Select 不在乎条件,它会映射所有内容,但重点是,它只会映射您想要精确映射的内容...

你不得不怀疑:

    究竟我需要从我拥有的所有这些值中映射什么? 我必须应用哪些条件才能仅过滤我需要的值(如果确实需要)?

希望能有所启发

【讨论】:

【参考方案2】:

如果选择它,您可以映射到新结构的 IEnumerable。

  A.Select(x=>new XUID=x.uid, UNAME=x.uname) 
  //input as [IEnumerable<A>] -------->  return output as [IEnumerable<X> ]

Where() 用作 IEnumerable 的过滤器,它将根据 where 子句返回结果。

A.Where(x=>x.uid!=0) //input as [IEnumerable<A>] -------->  return output as [IEnumerable<A> ]

【讨论】:

【参考方案3】:

Where ~= 过滤器

Select ~= 地图

两者都返回IEnumerable&lt;T&gt;

【讨论】:

这就是我来这里的目的!谢谢!【参考方案4】:

在哪里

找到匹配的项目并只返回匹配的项目(过滤)。

-> IEnumerable&lt;A&gt; 输入,IEnumerable&lt;A&gt; 输出

选择

为源中的所有项返回某些内容(投影/转换)。那东西可能是物品本身,但更常见的是某种投影。

->IEnumerable&lt;A&gt; 输入,IEnumerable&lt;B&gt; 输出

【讨论】:

Select 将始终返回列表中相同数量的元素(无论您可能有什么过滤条件)。 Where 可以根据您的过滤条件返回更少的元素。 而here 是select 的MSDN 示例,here 是where 的一个示例 至少对我来说,有一些其他语言的背景,认为Where == filterSelect == map是有帮助的【参考方案5】:

如果你知道他们是如何实现 Where 并选择扩展方法的,你就可以预测它在做什么...... 我尝试实现where和select扩展方法...你可以看看...

实施地点::

public static IEnumerable<Tsource> Where<Tsource> ( this IEnumerable<Tsource> a , Func<Tsource , bool> Method )


    foreach ( var data in a )
    
        //If the lambda Expression(delegate) returns "true" Then return the Data. (use 'yield' for deferred return)
        if ( Method.Invoke ( data ) )
        
            yield return data;
        
    

选择实施::

public static IEnumerable<TResult> Select<TSource , TResult> ( this IEnumerable<TSource> a , Func<TSource , TResult> Method )

    foreach ( var item in a )
    
        //Each iteration call the delegate and return the Data back.(use 'yield' for deferred return)
        yield return Method.Invoke ( item );
    

我的实现适用于任何集合...但它与 Microsoft 实现的扩展方法不同,因为它们使用表达式树来实现相同的。

【讨论】:

【参考方案6】:

SelectWhere 是作用于 IEnumerables 的两个完全不同的运算符。

第一个是我们所说的投影算子,而最后一个是限制算子

了解此类运算符行为的一种有趣方法是查看它们的“函数类型”。

选择:(IEnumerable, Func) → IEnumerable;它将包含 T1 类型元素的 IEnumerable 和将 T1 类型元素转换为 T2 类型元素的函数作为输入。输出是一个包含 T2 类型元素的 IEnumerable。

由此,我们可以很容易地猜到,该运算符将通过对输入 IEnumerable 的每个元素应用输入函数并将结果包装在一个新的 IEnumerable 中来产生其输出。

使用一些类似数学的符号,它将 (a, b, c, ...) : IEnumerablef : T1 → T2 作为输入并产生 (f(a), f(b), f(c), ...) :IEnumerable

其中:(IEnumerable, Func) → IEnumerable ;这个接受一个包含 T1 类型元素的 IEnumerable 和 T1 上的谓词(即,为 T1 类型的输入生成布尔结果的函数)。您会看到输出也是一个包含 T1 类型元素的 IEnumerable。

这一次人们会猜测输入 IEnumerable 的一个元素将出现在输出 IEnumerable 上,这取决于对元素应用谓词的结果。再加上运算符名称的语义,您可以确保它会生成输出 IEnumerable,方法是只从输入中获取那些在应用谓词时计算结果为 true 的元素。

具有函数式编程背景的人通常会这样想。它允许您仅通过查看运算符的类型来推断(或至少猜测......)运算符的作用!

作为练习,在查看文档之前,尝试查看 LINQ 在 IEnumerables 上引入的其他运算符并推断它们的行为!

【讨论】:

【参考方案7】:

它们是不同的:

Select 是关于转型

Where 是关于过滤的。

【讨论】:

【参考方案8】:

Select 将枚举映射到新结构。如果您对 IEnumerable 执行选择,您将获得一个具有相同数量元素的数组,但类型不同,具体取决于您指定的映射。 Where 过滤 IEnumerable,以便它为您提供原始 IEnumerable 的子集。

【讨论】:

以上是关于Linq:Select 和 Where 有啥区别的主要内容,如果未能解决你的问题,请参考以下文章

linq中where与skipwhile区别

在 SQL/MySQL 中,join 语句中的“ON”和“WHERE”有啥区别?

Linq语句

Linq TO Entities Exists 和 contains 之间的区别

LINQ操作符三:限制操作符

Linq to XML 后代和元素有啥区别