如何从列表中获取最后一条记录

本文关键字:最后 一条 记录 获取 列表 | 更新日期: 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();