tags:

views:

357

answers:

2

I recently faced an interview question related to LINQ.

What is the use of empty sequence?.He asked "if i suppose to ask you to use the one,where do you fit it?"

     public static IEnumerable<TResult> Empty<TResult>()
     {
        yield break;
     }

I did not answer it.Help is appreciated.

+4  A: 

If you had a loop that aggregated together different sets into a result set you can use it to initialize your result set variable and loop/accumulate. For example:

IEnumerable<string> results = Enumerable.Empty<string>();

for(....)
{
    IEnumerable<string> subset = GetSomeSubset(...);

    results = results.Union(subset);
}

Without Empty you'd have to have written a null check into your loop logic:

IEnumerable<string> results = null;

for(....)
{
    IEnumerable<string> subset = GetSomeSubset(...);

    if(results == null)
    {
        results = subset;
    }
    else
    {
        results = results.Union(subset);
    }
}

It doesn't just have to be a loop scenario and it doesn't have to be Union (could be any aggregate function), but that's one of the more common examples.

Drew Marsh
Thank you very much drew forgiving excellent example
Good answer to the question posed. Readers should note that my performance comment above also applies to this code. Using Union this way is O(Nsquared) because it creates a Set for each union and fills it with all strings so far. Well I guess that's technically O(NM). The point it that it is very slow and SelectMany/Distinct is much better for this kind of scenario.
Ray Burns
+3  A: 

You can use this when you want to quickly create an IEnumerable<T> this way you don't have to create a reference to a new List<T> and take advantage of the yield keyword.

List<string[]> namesList =
    new List<string[]> { names1, names2, names3 };

// Only include arrays that have four or more elements
IEnumerable<string> allNames =
    namesList.Aggregate(Enumerable.Empty<string>(),
    (current, next) => next.Length > 3 ? current.Union(next) : current);

Note the use of Union because it is not a List you can not call Add method, but you could call Union on an IEnumerable

Stan R.
You might get better performance using Concat instead of Union, unless you really need to exclude duplicates.
Joel Mueller
The fastest way of all to join a bunch of lists like that using LINQ is namesList.SelectMany(list => list.Length>4 ? list : Enumerable.Empty<string>()).Distinct(). Doing it with Aggregate and Union is extremely inefficient. Aggregate and Concat is better but is still O(Nsquared) and O(N) space. SelectMany/Distinct is O(N) and O(1) space (just 3 objects are created).
Ray Burns