C# 如何使用Lambda从列表中获取最后x条记录
我有一个字符串列表,其中我删除了每个重复项,现在我想对它进行更多的过滤,以获得最后5条记录。我该怎么做 到目前为止我得到了什么C# 如何使用Lambda从列表中获取最后x条记录,c#,lambda,c#-4.0,C#,Lambda,C# 4.0,我有一个字符串列表,其中我删除了每个重复项,现在我想对它进行更多的过滤,以获得最后5条记录。我该怎么做 到目前为止我得到了什么 List<string> query = otherlist.Distinct().Select(a => a).ToList(); List query=otherlist.Distinct().Select(a=>a.ToList(); 这个怎么样 var lastFive = list.Reverse().Take(5).Reverse();
List<string> query = otherlist.Distinct().Select(a => a).ToList();
List query=otherlist.Distinct().Select(a=>a.ToList();
这个怎么样
var lastFive = list.Reverse().Take(5).Reverse();
编辑:事情是这样的-
var lastFiveDistinct = otherlist.Distinct()
.Reverse()
.Take(5)
.Reverse()
.ToList();
还要注意的是,如果最后有一个
ToList()
调用,则不应调用它query
,因为这样它就不再是查询了,而是经过计算并变成了一个列表。如果只需要对其进行迭代,可以省略ToList()
调用,并将其保留为IEnumerable
您不需要。选择(a=>a)
。那是多余的
你可以跳过剩下的5条记录,如
List<string> query = otherlist.Distinct().ToList();
List<string> lastFive = query.Skip(query.Count-5).ToList();
List query=otherlist.Distinct().ToList();
List lastFive=query.Skip(query.Count-5.ToList();
编辑:
我错过了数据列表。对于IEnumerable编辑来说,这种方法更适合于非列表输入,现在处理
IEnumerable
并检查这是否是一个IList
;如果没有,它将通过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];
}
}
公共静态IEnumerable TakeLast(
此IEnumerable源(整数计数)
{
IList list=(源代码为IList)??source.ToList();
count=Math.Min(count,list.count);
for(int i=list.Count-Count;i
为什么选择(a=>a)
?它什么都没做……我的“傻瓜”就是把最后的x记录过滤掉。我敢说,计数元素然后使用Skip and Take会更便宜。反转IEnumerable并不便宜。无论哪种方式,它的渐进复杂性都是一样的,但你是对的,skip/take可能更快。事实上,我将修改我之前的陈述-我认为不会有明显的性能差异。请看我对Jens答案的评论。Skip()的性能明显优于Reverse()然后Take()。@Danny:没有你想象的那么好:ToList()
调用将与我的第一个Reverse()
(遍历整个列表一次)一样昂贵,在Take(5)
之后,它只是在反转五个元素,这是微不足道的。而且,我的方式不会创建中间列表。@tzaman-“我的方式不会创建中间列表”-是的,它会;事实上,其中有两个。您认为Reverse
是如何操作的?(严格来说,它创建了一个T[]
数组,由Buffer
-提供,但区别相同)@Marc-huh。当然我真傻。尽管如此,我刚才做的一点计时似乎表明我的解决方案比这个(或你的)运行得更快。看一看?绝对地如果您知道它是一个列表,那么这是一个简单且容易实现的最有效的方法;ToList()
只需在末尾执行一次。
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];
}
}