在 C# 中获取 Collection/List/Dictionary 的最后 5 项?

Grab last 5 items of a Collection/List/Dictionary in C#?

我有一个 class:

public class MatchItem
{
    public string round { get; set; }
    public string player1 { get; set; }
    public string player2 { get; set; }
    public string scores { get; set; }
}

最初我使用的是字典:

private Dictionary<string, MatchItem> results = new Dictionary<string, MatchItem>();

字典允许我使用散列字符串作为索引键来访问 MatchItem 值。

但是,现在我有一个新的需求。我希望能够访问添加到字典中的最后 X 个项目。执行此操作的最佳方法是什么?

您可以使用 Skip 方法获取最后的 X 项,但您应该记住 Dictionary 没有订单,因此这可能无法按预期工作,但是它适用于有序集合,例如 List<T>:

var items = results.Skip(results.Count - 5).Select(x => x.Value);

如果您确实必须将您的值保存在字典中,那么您将需要一个帮助程序集合来保持条目顺序或条目时间。在我的示例中,我将它打包在一个非常简单的包装器 class OrderedDictionary 中,但这并不意味着您必须有一个包装器 class。您可以轻松地将保持输入时间的助手集合添加到您拥有字典的 class。

向词典添加条目时,您必须更新助手词典。在这里我选择 DateTime.Now.Ticks 来保持条目的顺序。然后,当 returning 项目时,我按降序输入时间对集合进行排序,获取请求的键数量,在主字典中搜索这些键,然后 return 结果。

public class OrderedDictionary<T, K>
{
    private Dictionary<T, K> baseDictionary;
    private Dictionary<long, T> entryTimeDictionary;

    public OrderedDictionary()
    {
        this.baseDictionary = new Dictionary<T, K>();
    }

    public void Add(T key, K val)
    {
        this.baseDictionary[key] = val;
        this.entryTimeDictionary[DateTime.Now.Ticks] = key;
    }

    public List<KeyValuePair<T, K>> GetLastEnteredItems(int numberOfEntries)
    {
        // Find n last keys.
        var lastEntries = 
            this.entryTimeDictionary
                .OrderByDescending(i => i.Key)
                .Take(numberOfEntries)
                .Select(i => i.Value);

        // Return KeyValuePair for itmes with last n keys
        return this.baseDictionary
                   .Where(i => lastEntries.Contains(i.Key))
                   .ToList();
    }
}

如前所述,您可以在 class 中使用相同的机制。但是,如果您决定创建自己的包装器 class,它可能应该实现 IDictionary、ICollection 和 IEnumerable 接口。