【问题标题】:Add linq property selector to Expression将 linq 属性选择器添加到表达式
【发布时间】:2015-10-12 00:41:33
【问题描述】:

我在 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;
        }
    }
} 

我需要像这样添加一个选择器:

.NextDistinct(i => i.articlepricehistory_sell)

我试过了,但是键选择不能正常工作:

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;
                }                
            }
        }

更新:

这是我的查询,我只需要使用 articlepricehistory_sell 列进行区分

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();

结果:

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.

预期结果:

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.

【问题讨论】:

  • 是的,您的函数定义似乎正确,但您必须使用 keySelector 参数
  • 请告诉我如何使用,我只更改函数定义以接受属性选择器,但我不知道如何在函数内部使用它。
  • Keyselector 现在是一个可以调用的函数。它接受一个 tsource 类型的参数并返回一个 tkey 类型的对象。
  • 我试过:foreach (TSource item in source.Select(keySelector))
  • 请查看我更新的问题,如果我只在查询中选择一列,但我需要选择两列双精度,日期时间类型,所以这就是问题开始的地方,因为所有日期都不同,所以我占用了一个选择器

标签: c# .net linq collections


【解决方案1】:

您只需将TSource previous 替换为TKey previousKey 并将其与当前项目键(均使用传递的选择器提取)进行比较。此外,最好允许为您的两个函数选择指定一个比较器。有问题的函数可能是这样的

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;
        }
    }
}

【讨论】:

  • 非常感谢,这正是我所需要的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多