すべての null を含めたい場合は、null プロパティを null の場合に一意のものに置き換える必要があります。プロパティが文字列であると仮定すると、Guid はこの仕事に適しています。
.DistinctBy(m => m.SomeUniqueMovieProperty ?? Guid.NewGuid().ToString())
null 値を持つプロパティにヒットするたびに、ランダムな新しい GUID 値が入力されます。
空のタイトルも削除されないようにする場合は、クエリを次のように変更します
.DistinctBy(m => String.IsNullOrEmpty(m.SomeUniqueMovieProperty) ? Guid.NewGuid().ToString() : m.SomeUniqueMovieProperty)
もう 1 つのオプションは、希望DistinctBy
どおりに動作する独自のものを作成することです。これは元のソースを微調整したバージョンで、true を返す場合にのみフィルターを適用しますshouldApplyFilter
。簡潔にするためにコメントも削除されています。
static partial class MoreEnumerable
{
public static IEnumerable<TSource> ConditionalDistinctBy<TSource, TKey>(this IEnumerable<TSource> source,
Func<TSource, TKey> keySelector, Func<TKey, bool> shouldApplyFilter)
{
return source.ConditionalDistinctBy(keySelector, shouldApplyFilter, null);
}
public static IEnumerable<TSource> ConditionalDistinctBy<TSource, TKey>(this IEnumerable<TSource> source,
Func<TSource, TKey> keySelector, Func<TKey, bool> shouldApplyFilter, IEqualityComparer<TKey> comparer)
{
if (source == null) throw new ArgumentNullException("source");
if (keySelector == null) throw new ArgumentNullException("keySelector");
if (shouldApplyFilter == null) throw new ArgumentNullException("shouldApplyFilter");
return ConditionalDistinctByImpl(source, keySelector, shouldApplyFilter, comparer);
}
private static IEnumerable<TSource> ConditionalDistinctByImpl<TSource, TKey>(IEnumerable<TSource> source,
Func<TSource, TKey> keySelector, Func<TKey, bool> shouldApplyFilter, IEqualityComparer<TKey> comparer)
{
var knownKeys = new HashSet<TKey>(comparer);
foreach (var element in source)
{
var key = keySelector(element);
if (shouldApplyFilter(key) && knownKeys.Add(key))
{
yield return element;
}
}
}
}
次のように使用されます
.ConditionalDistinctBy(m => m.SomeUniqueMovieProperty, s => !String.IsNullOrEmpty(s));