Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C# LINQ SelectMany with Default

I am looking for an elegant solution to aggregate a child collection in a collection into one large collection. My issue is when certain child collections could be null.

EG:

var aggregatedChildCollection = parentCollection.SelectMany(x=> x.ChildCollection);

This throws an exception should any of the child collection objects be null. Some alternatives are:

// option 1
var aggregatedChildCollection = parentCollection
    .Where(x=>x.ChildCollection != null)
    .SelectMany(x => x.ChildCollection);

// option 2
var aggregatedChildCollection = parentCollection
    .SelectMany(x => x.ChildCollection ?? new TypeOfChildCollection[0]);

Both would work but I am doing a certain operation on quite a few child collections on the parent, and it is becoming a bit unweilding.

What I would like is to create an extension method that checks if the collection is null and if so does what option 2 does - adds an empty array. But my understanding of Func is not to a point where I know how to code this extension method. I do know that the syntax I would like is like this:

var aggregatedChildCollection = parentCollection.SelectManyIgnoringNull(x => x.ChildCollection);

Is there a simple extension method that would accomplish this?

like image 911
DenverCoder9 Avatar asked Sep 05 '16 23:09

DenverCoder9


People also ask

What C is used for?

C programming language is a machine-independent programming language that is mainly used to create many types of applications and operating systems such as Windows, and other complicated programs such as the Oracle database, Git, Python interpreter, and games and is considered a programming foundation in the process of ...

What is C full form?

Full form of C is “COMPILE”. One thing which was missing in C language was further added to C++ that is 'the concept of CLASSES'.

Is C language easy?

C is a general-purpose language that most programmers learn before moving on to more complex languages. From Unix and Windows to Tic Tac Toe and Photoshop, several of the most commonly used applications today have been built on C. It is easy to learn because: A simple syntax with only 32 keywords.

What is C language basics?

What is C? C is a general-purpose programming language created by Dennis Ritchie at the Bell Laboratories in 1972. It is a very popular language, despite being old. C is strongly associated with UNIX, as it was developed to write the UNIX operating system.


3 Answers

You can use a custom extension method:

public static IEnumerable<TResult> SelectManyIgnoringNull<TSource, TResult>(
    this IEnumerable<TSource> source, 
    Func<TSource, IEnumerable<TResult>> selector)
{
    return source.Select(selector)
        .Where(e => e != null)
        .SelectMany(e => e);
}

And use like this:

var aggregatedChildCollection = parentCollection
    .SelectManyIgnoringNull(x => x.ChildCollection);
like image 156
DavidG Avatar answered Sep 25 '22 14:09

DavidG


You can avoid the overhead from the LINQ extension by using the SelectMany Reference Source

public static IEnumerable<TResult> SelectManyNotNull<TSource, TResult>(
         this IEnumerable<TSource> source, Func<TSource, IEnumerable<TResult>> selector) 
{
    foreach (TSource element in source)
    {
        var subElements = selector(element);
        if (subElements != null)
            foreach (TResult subElement in subElements )
                yield return subElement;
    }
}
like image 22
Slai Avatar answered Sep 23 '22 14:09

Slai


If ParentCollection is your own class you should also be able to a default constructor to the class such as:

public ParentCollection{
    public ParentCollection() {
        ChildCollection = new List<ChildCollection>();
    }
}

That should prevent the null ref exception and give you an empty list if it doesn't have anything in it. At least this works with EF models.

like image 37
Eonasdan Avatar answered Sep 26 '22 14:09

Eonasdan