Reputation: 513
I have the following Expression in Linq:
public static IEnumerable<T> NextDistinct<T>(this IEnumerable<T> items)
{
T previous = default(T);
bool first = true;
foreach(T item in items)
{
if (first || !Equals(previous, item))
{
first = false;
previous = item;
yield return item;
}
}
}
I need to add a Selector like this:
.NextDistinct(i => i.articlepricehistory_sell)
I tried, but the key select doesn't work correctly:
public static IEnumerable<TSource> NextDistinct<TSource, TKey>(this IEnumerable<TSource> source,
Func<TSource, TKey> keySelector)
{
TSource previous = default(TSource);
bool first = true;
foreach (TSource item in source)
{
if (first || !Equals(previous, item))
{
first = false;
previous = item;
yield return item;
}
}
}
UPDATE:
This is my query i need to do a distinct only using the articlepricehistory_sell column
var ArticlesSellHistory = dt.AsEnumerable()
select new
{
articlepricehistory_sell = articlespricehistory.Field<Double>("articlepricehistory_sell"),
articlepricehistory_date = articlespricehistory.Field<DateTime>("articlepricehistory_date")
})
.NextDistinct(i => i.articlepricehistory_sell)
.ToList();
Result:
365 05/09/2015 02:30:31 p.m.
370 11/10/2015 04:19:37 p.m.
369.59 11/10/2015 04:19:54 p.m.
365 11/10/2015 04:20:05 p.m.
365 11/10/2015 04:20:58 p.m.
365 11/10/2015 04:33:22 p.m.
Expected Result:
365 05/09/2015 02:30:31 p.m.
370 11/10/2015 04:19:37 p.m.
369.59 11/10/2015 04:19:54 p.m.
365 11/10/2015 04:20:05 p.m.
Upvotes: 0
Views: 119
Reputation: 205719
All you need is to replace TSource previous
with TKey previousKey
and compare it to the current item key (both extracted using the passed selector). Also it's good to allow optionally specifying a comparer for both your functions. The function in question could be like this
public static IEnumerable<TSource> NextDistinct<TSource, TKey>(
this IEnumerable<TSource> source,
Func<TSource, TKey> keySelector,
IEqualityComparer<TKey> keyComparer = null)
{
if (source == null) throw new ArgumentNullException("source");
if (keySelector == null) throw new ArgumentNullException("keySelector");
if (keyComparer == null) keyComparer = EqualityComparer<TKey>.Default;
var previousKey = default(TKey);
bool first = true;
foreach (TSource item in source)
{
var itemKey = keySelector(item);
if (first || !keyComparer.Equals(previousKey, itemKey))
{
yield return item;
first = false;
previousKey = itemKey;
}
}
}
Upvotes: 2