So, the main implementation would be like this :
private static int DistinctCountIterator<TSource>CountDistinctIterator<TSource>(IEnumerable<TSource> source, Func<TSource, bool> predicate, IEqualityComparer<TSource> comparer)
{
if (source == null) throw new ArgumentNullException(nameof(source));
var set = new HashSet<TSource>(comparer);
var count = 0;
foreach (TSource element in source)
{
checked
{
if (set.Add(element) && predicate(element))
{
count++;
}
}
}
return count;
}
Now, it's ofa matter of calling back this method with the appropriate arguments.
public static int DistinctCount<TSource>CountDistinct<TSource>(this IEnumerable<TSource> source)
{
return DistinctCountIterator<TSource>CountDistinctIterator<TSource>(source, (s) => true, null);
}
public static int DistinctCount<TSource>CountDistinct<TSource>(this IEnumerable<TSource> source, IEqualityComparer<TSource> comparer)
{
return DistinctCountIterator<TSource>CountDistinctIterator<TSource>(source, (s) => true, comparer);
}
public static intbool DistinctCount<TSource>AnyDistinct<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate)
{
return DistinctCountIterator<TSource>CountDistinctIterator<TSource>(source, predicate, null); == 1;
}
public static intbool DistinctCount<TSource>AnyDistinct<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate, IEqualityComparer<TSource> comparer)
{
return DistinctCountIterator<TSource>CountDistinctIterator<TSource>(source, predicate(s) => true, comparernull); == 1;
}
to something meaningful other than DistinctCount
like for instance DistinctAny
which return boolean (true if DistinctCount
returns 1, false if 0).
UPDATE :
I have changed the methods name from DistinctCount
to CountDistinct
the reason of this is because the method is Counting
, so the Count needs to be first so it would be easier to picked up, the other reason is doing this will make it appear after Count
on the intellisense list. I also added AnyDistinct
methods which replaced the mentioned method (the one with Func<TSource, bool>
).