Problem
I am looking for a way to implement FirstOrEmpty
for a IEnumerable<X>
where X implements IEnumerable<T>
. Basically, if the predicate does not match anything, return Enumerable<T>.Empty
. I do not want to constrain the source parameter to IEnumerable<IEnumerable<X>>
or because I might want to pass in something that implement IEnumerable<X>
(e.g. IEnumerable<IGrouping<bool, X>>
).
Usage Example
IEnumerable<T> myCollection;
var groupCheck = myCollection.GroupBy(t => t.SomeProp == 23);
var badGroup = groupCheck.FirstOrEmpty(t => !t.Key);
var goodGroup = groupCheck.FirstOrEmpty(t => t.Key);
foreach(T x in badGroup) { ... }
foreach(T x in goodGroup) { ... }
Old way:
IEnumerable<T> myCollection = ...;
var groupCheck = myCollection.GroupBy(t => t.SomePropOnClassT == 23);
var badGroup = (groupCheck.FirstOrDefault(t => !t.Key) ?? Enumerable<T>.Empty);
var goodGroup = (groupCheck.FirstOrDefault(t => t.Key) ?? Enumerable<T>.Empty);
foreach(T x in badGroup) { ... }
foreach(T x in goodGroup) { ... }
Attempts
Attempt 1:
public static IEnumerable<TResult> FirstOrEmpty<TSource, TResult>(
this IEnumerable<TSource> source,
Func<TSource, bool> predicate) where TSource : IEnumerable<TResult>
{
TSource tmp = source.FirstOrDefault(predicate);
if(tmp != null) {
foreach(TResult x in tmp)
{
yield return x;
}
}
}
Attempt 2:
public static IEnumerable<TResult> FirstOrEmpty<TSource, TResult>(
this IEnumerable<TSource> source,
Func<TSource, bool> predicate) where TSource : IEnumerable<TResult>
{
TSource tmp = source.FirstOrDefault(predicate);
return tmp == null ? Enumerable.Empty<TResult>() : tmp;
}