【问题标题】:Filtering Null values in Select在 Select 中过滤 Null 值
【发布时间】:2008-12-31 00:30:37
【问题描述】:

我有 IQueryable 类型的 T 对象列表,我想将其转换为 K 类型的对象

List<K> tranformedList = originalList.Select(x => transform(x)).ToList();

如果转换函数无法转换对象,则返回 null。如果我想过滤掉 null 元素,我可以调用

List<K> tranformedList = originalList.Select(x => transform(x))
                                     .Where(y => y != default(K))
                                     .ToList();

或者在 LINQ 中调用 Select 时是否有其他方法可以过滤掉空元素?

【问题讨论】:

  • 你会接受 IEnumerable 的解决方案吗? IQueryable 可能稍微复杂一些,但也许您只需要 IEnumerable 支持。

标签: linq


【解决方案1】:

你不能这样做吗:

List<K> tranformedList = originalList.Select(x => tranform(x))
                                 .Where(y => y != null) //Check for nulls
                                 .ToList();

【讨论】:

    【解决方案2】:

    怎么样

        List<K> tranformedList = originalList
                                 .Select(transform)
                                 .OfType<K>()
                                 .ToList()
    

    同时负责拆箱和去除空值(尤其是当 K 是一个结构体时)

    David B 我不相信您的代码 .Where(y =&gt; y != null) 在 K 是 int 时有效!如果 K 是 int,您将无法编译该代码!

    【讨论】:

    • 很好的答案,这就是这样做的方法。
    • 我喜欢这个答案。您能否将.OfType&lt;object&gt; 作为一种更通用的方法,因为 null 永远不会是对象类型,但任何其他对象都会?或者这会导致计算成本高昂的装箱/拆箱(您提到的)?
    • 与“.Select([...]).Where(y => y != null)”的性能差异是什么?我可以想象后者迭代两次集合,".Select([...]).OfType()" 是做什么的?
    • 很好的答案 - 生成一个不可为空的类型列表
    【解决方案3】:
    List<K> tranformedList = originalList.Select(x => transform(x))
                                         .Where(y => !string.IsNullOrEmpty(y))
                                         .ToList();
    

    在 Select linq 查询之后,在 Where 查询中使用 !string.IsNullOrEmpty("string")string.IsNullOrWhiteSpace("string") 过滤空值。

    【讨论】:

    • 使用 asn Iqueryable 时请注意,一些 ODBC 无法识别 isNullOrEmpty 和其他专有 C# 类方法
    【解决方案4】:

    使用 Where 代替 Select (Linq)。

    Where 直接返回不带空值的列表

    List transformedList = originalList.Where(x => x != null).ToList();

    【讨论】:

    • Where&lt;T&gt;() 将返回 IEnumerable&lt;T&gt;,这将是原始集合的某个子集。 Select&lt;T, TResult&gt;() 将返回 IEnumerable&lt;TResult&gt;,根据旧对象集和提供的函数(接受 T 类型的项目),选择了一些新对象集。无论传递给Select()Func 的返回类型是什么,都将决定您返回的对象类型。而且,即使 T == TResult,结果集也可能不是相同的项目,甚至是原始项目的子集。所以 Select 和 Where 根本不是等价的,Where 在这里不是一个好的选择。
    【解决方案5】:

    您可以尝试一个 for 循环并将非空值添加到新的转换列表中。

    foreach (var original in originalList)
    {
        K transformed = tranform(orignal);
        if (transformed != null)
        {
            tranformedList.Add(transformed);
        }
    }
    

    或者你可以试试

            List<K> tranformedList = (from t in
                                          (from o in originalList
                                           select tranform(o))
                                      where t != null
                                      select t).ToList();
    

    我认为 Nathan 的作品也不错,但不那么冗长

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-10-31
      • 2019-09-03
      • 1970-01-01
      • 1970-01-01
      • 2019-08-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多