76

I have IQueryable list of objects of type T which I want to transform into objects of type K

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

the transform function returns null if it cannot tranform the objects.If I want to filter out null elements can I call

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

or is there any other way of filtering out null elements when calling Select in LINQ ?

Mitch Wheat
  • 295,962
  • 43
  • 465
  • 541
fatbuddha
  • 987
  • 1
  • 6
  • 8
  • Will you accept solutions for IEnumerable? IQueryable is potentially a little more complicated, but perhaps you only need IEnumerable support. – DuckMaestro Oct 17 '14 at 23:09

5 Answers5

99

Can't you just do something like this:

List<K> tranformedList = originalList.Select(x => tranform(x))
                                 .Where(y => y != null) //Check for nulls
                                 .ToList();
Nathan W
  • 54,475
  • 27
  • 99
  • 146
79

What about

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

Takes care of unboxing an getting rid of nulls at the same time (especially when K is a struct)

David B I dont believe you that your code .Where(y => y != null) works when K is an int! There is NO WAY you will get that code to compile if K is an int!

StayOnTarget
  • 11,743
  • 10
  • 52
  • 81
stitty
  • 972
  • 9
  • 10
  • Excellent answer, this is the way to do it. – ciscoheat Aug 23 '11 at 10:15
  • 3
    I like this answer. Could you do `.OfType` as a more generic approach, as null will never be of type object, but any other object will? Or will this cause boxing/unboxing (which you mention) which is computationally expensive? – theyetiman Jan 17 '13 at 13:18
  • What is the performance difference with ".Select([...]).Where(y => y != null)"? I could imagine the latter iterates twice a collection, what does ".Select([...]).OfType()" do? – Cees Mar 03 '16 at 12:52
  • Great answer - results in a non-nullable type list – Gilbert Mar 23 '22 at 07:19
1
List<K> tranformedList = originalList.Select(x => transform(x))
                                     .Where(y => !string.IsNullOrEmpty(y))
                                     .ToList();

After your Select linq query, filter null values with !string.IsNullOrEmpty("string") or string.IsNullOrWhiteSpace("string") in your Where query.

Ben
  • 501
  • 6
  • 20
  • 1
    Just take care when using asn Iqueryable, some ODBC couuld not recognize the isNullOrEmpty and other exclusive C# class methods – jefissu Mar 07 '22 at 12:27
0

Use Where Instead of Select (Linq).

Where returns the list without null values directly

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

  • `Where()` will return `IEnumerable`, which will be some subset of the original set. `Select()` will return `IEnumerable`, some set of new objects selected, based on the old set of objects and the function provided (which accepts an item of type T). Whatever the return type of the `Func` passed to `Select()` will determine what type of object you get back. Moreover, even if T == TResult, the result set may not be the same items, or even a subset of the original items. So Select and Where are not equivalent at all really, and Where isn't a good choice here. – Eric Lease Feb 17 '21 at 05:35
-1

You could try a for loop and add the non nulls to the new transformed list.

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

or you could try

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

I think Nathan's works as well but is less verbose

Noah
  • 13,821
  • 4
  • 36
  • 45