You can write your own extension method that works like the built-in LINQ methods:
public static class Extensions
{
public static IEnumerable<T> DistinctWhere<T>(this IEnumerable<T> input, Func<T,bool> predicate)
{
HashSet<T> hashset = new HashSet<T>();
foreach(T item in input)
{
if(!predicate(item))
{
yield return item;
continue;
}
if(!hashset.Contains(item))
{
hashset.Add(item);
yield return item;
}
}
}
}
The usage is
int[] input = new int[] { 0,0,0,1,1,1,1,1,2,2 };
int[] result = input.DistinctWhere(x => x > 0).ToArray();
Online demo: https://dotnetfiddle.net/QDpCDF
EDIT: If you want to use a property of the objects in your list (like an ID property), you can add some slight modifications to the method:
public static class Extensions
{
public static IEnumerable<T> DistinctWhere<T,T2>(this IEnumerable<T> input, Func<T,T2> selector, Func<T2,bool> predicate)
{
HashSet<T2> hashset = new HashSet<T2>();
foreach(T item in input)
{
T2 value = selector.Invoke(item);
if(!predicate.Invoke(value))
{
yield return item;
continue;
}
if(!hashset.Contains(value))
{
hashset.Add(value);
yield return item;
}
}
}
}
The usage is
TypeWithId[] input = new TypeWithId[]
{
new TypeWithId { ID = 0 } ,
new TypeWithId { ID = 0 } , //... also initialize the other items
};
TypeWithId[] result = input.DistinctWhere(x => x.ID, x => x > 0).ToArray();
3
solved Prevent duplicates from array, based on condition [closed]