如何从列表中获取最后一条记录
本文关键字:最后 一条 记录 获取 列表 | 更新日期: 2023-09-27 17:58:42
我有如下列表
static List<MessageDetail> CurrentMessage = new List<MessageDetail>();
动态地,分配给该列表的值,例如:
CurrentMessage.Add(new MessageDetail { UserName = 123,GroupName = somegrp, Message = somemsg });
在这里,我想录下最后5张左右的唱片。
// this returns first 5 result, dont want to user orderby clause either
CurrentMessagesForGroup = CurrentMessage
.Where(c => c.GroupName == groupName)
.Take(5).ToList();
有没有办法实现TakeLast()
属性?或者任何形式的帮助都将不胜感激。谢谢你抽出时间。
使用skip
:
CurrentMessagesForGroup = CurrentMessage
.Where(c => c.GroupName == groupName).Skip(Math.Max(0, CurrentMessage.Count() - 5)).ToList();
编辑:我还发现我认为它更容易使用(MoreLinq):
using MoreLinq;
var CurrentMessagesForGroup2 = CurrentMessage.TakeLast(5);
使用OrderBy(ASC或DESC)为Take操作正确排列记录。
升序:
CurrentMessagesForGroup = CurrentMessage
.Where(c => c.GroupName == groupName)
.OrderBy(c => c.GroupName)
.Take(5)
.ToList();
或下降:
CurrentMessagesForGroup = CurrentMessage
.Where(c => c.GroupName == groupName)
.OrderByDescending(c => c.GroupName)
.Take(5)
.ToList();
如果有人使用DotNet Core 2或以上版本或DotNet Standard 2.1或以上版本,那么您可以使用内置在.TakeLast()
中的Linq
参考:此处的Microsoft文档
您可以使用Reverse()
,这有点反常。
CurrentMessagesForGroup = CurrentMessage
.Where(c => c.GroupName == groupName)
.Reverse()
.Take(5).ToList();
我为此使用了一个扩展方法。
public static IEnumerable<T> TakeLast<T>(this IEnumerable<T> source, int numElements)
{
return source.Skip(Math.Max(0, source.Count() - numElements));
}
使用它:
CurrentMessagesForGroup = CurrentMessage.Where(c => c.GroupName == groupName).TakeLast(5).ToList();
编辑:这归功于使用Linq来获取集合的最后N个元素?
我喜欢这个实现,它使用了一个循环缓冲区。
public static IEnumerable<T> TakeLast<T>(this IEnumerable<T> input, int n)
{
if (n == 0)
yield break;
int tail = 0;
int head = 0;
int count = 0;
T[] buffer = new T[n];
foreach (T item in input)
{
buffer[tail] = item;
tail = (tail + 1) % n;
if (count < n)
count++;
else
head = (head + 1) % n;
}
for (int i = 0; i < count; i++)
yield return buffer[(head + i) % n];
}
如果MessageDetails类具有数字Id或创建日期时间,我们可以使用
var lastRecords= CurrentMessage.OrderByDescending(i=>i.Id).Where(p=>p.GroupName==groupName).Take(5).ToList();