【问题标题】: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 时,情况更是如此

标签: .net linq select where


【解决方案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 不在乎条件,它会映射所有内容,但重点是,它只会映射您想要精确映射的内容...

你不得不怀疑:

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

希望能有所启发

【讨论】:

    【解决方案2】:

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

      A.Select(x=>new X{UID=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 可以根据您的过滤条件返回更少的元素。
      • hereselect 的MSDN 示例,herewhere 的一个示例
      • 至少对我来说,有一些其他语言的背景,认为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 的子集。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2018-02-18
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2010-09-22
              • 2015-07-12
              相关资源
              最近更新 更多