【问题标题】:How to get last x records from a list with Lambda如何使用 Lambda 从列表中获取最后 x 条记录
【发布时间】:2010-07-08 09:07:25
【问题描述】:

我有一个字符串列表,其中我删除了每个重复项,现在我想进一步过滤它以获得最后 5 条记录。我该怎么做?

到目前为止我得到了什么

 List<string> query = otherlist.Distinct().Select(a => a).ToList();

【问题讨论】:

  • 为什么是Select(a =&gt; a)?它没有做任何事情......
  • 那是我放置最后 x 个记录过滤器的“假人”

标签: c# lambda c#-4.0


【解决方案1】:

您不需要.Select(a =&gt; a)。那是多余的。

你可以得到最后 5 条记录,跳过其余的就像

List<string> query = otherlist.Distinct().ToList();
List<string> lastFive = query.Skip(query.Count-5).ToList();

【讨论】:

  • Skip() 的性能明显优于 Reverse() 然后 Take()。
  • @Danny:没有你想象的那么多:ToList() 调用将和我的第一个Reverse() 一样昂贵(遍历整个列表一次),在Take(5) 之后它只是颠倒了花生的五个元素。另外,我的方式不会创建中间列表。
  • @tzaman - “我的方式不会创建中间列表” - 是的;其中两个,事实上。你认为Reverse 是如何运作的? (好吧,严格来说,它创建了一个 T[] 数组,由 Buffer&lt;T&gt; 提供 - 但相同的区别)
  • @Marc - 嗯。当然;我真傻。尽管如此,我刚刚做的一些时间似乎表明我的解决方案比这个(或你的)运行得更快。看一看? pastebin.com/a65UMZfP
【解决方案2】:

edit 以适应非列表输入,现在处理 IEnumerable&lt;T&gt; 和 检查 如果这是 IList&lt;T&gt;;如果不是,它会通过ToList() 对其进行缓冲,这有助于确保我们只读取数据一次(而不是可能会多次读取数据的.Count() 和.Skip())。

由于这是一个列表,我倾向于编写一个扩展方法来充分利用它:

    public static IEnumerable<T> TakeLast<T>(
           this IEnumerable<T> source, int count)
    {
        IList<T> list = (source as IList<T>) ?? source.ToList();
        count = Math.Min(count, list.Count);
        for (int i = list.Count - count; i < list.Count; i++)
        {
            yield return list[i];
        }
    }

【讨论】:

  • 当然。鉴于您知道它是一个列表,这是一种简单易行的最有效方法。
  • 除非它从Distinct() 调用中出来时不会是一个列表; ToList() 最后只需要发生一次。
【解决方案3】:

这个怎么样?

var lastFive = list.Reverse().Take(5).Reverse();

编辑:这就是全部 -

var lastFiveDistinct = otherlist.Distinct()
                                .Reverse()
                                .Take(5)
                                .Reverse()
                                .ToList();

还请注意,如果您最后有一个 ToList() 呼叫,则不应将其称为 query,因为那样它就不再是 查询,它已被评估并变成一个列表。如果您只需要它进行迭代,您可以省略ToList() 调用并将其保留为IEnumerable。

【讨论】:

  • 我敢冒险计算元素然后使用 Skip and Take 会更便宜。反转 IEnumerable 并不便宜。
  • 无论哪种方式都具有相同的渐近复杂性,但您是对的,skip/take 可能更快。
  • 实际上,我会修改我之前的声明——我认为不会有明显的性能差异。请参阅我对 Jens 回答的评论。
【解决方案4】:
var count=list.Count();
var last5=list.Skip(count-5);

编辑:

我错过了数据是 List 。这种方法对于 IEnumerable

会更好

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-10-01
    • 2011-08-18
    • 1970-01-01
    • 1970-01-01
    • 2012-10-15
    • 2012-04-11
    • 2018-10-12
    • 2015-08-13
    相关资源
    最近更新 更多