在 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 接口。
我有一个 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 接口。