如果我有
record R(string Name, int Id);
var rList = new List<R>()
{
new R("Fred", 2),
new R("Fred", 3),
new R("Fred", 4),
new R("Jim", 10),
};
是否可以创建一个查找,其中每个存储桶都可以被索引?
例如:
var lk = rList.ToLookup(r => r.Name);
var fred1 = lk["Fred"][0];
var fred2 = lk["Fred"][1];
var harryCount = lk["Harry"].Count();
我不想使用
Dictionary
,因为 lk["Harry"]
会抛出异常。
谢谢
使用此代码片段:
ILookup<string, R> lk = people.ToLookup(t => t.Name);
var freds = lk["Fred"].ToList();
var fred1 = freds[0];
var fred2 = freds[1];
var harryCount = lk["Harry"].Count();
ElementAt
LINQ 运算符来代替第二个索引器:
var lk = rList.ToLookup(r => r.Name);
var fred1 = lk["Fred"].ElementAt(0);
var fred2 = lk["Fred"].ElementAt(1);
实现
IGrouping<TKey, TElement>
接口的内部 .NET 类也实现 IList<TElement>
接口(源代码)。此外,ElementAt
运算符包括对实现IList<T>
接口(源代码)的可枚举序列的优化,将操作的计算复杂度从 O(n) 降低到 O(1):
public static TSource ElementAt<TSource>(this IEnumerable<TSource> source, int index)
{
/* ... */
else if (source is IList<TSource> list)
{
return list[index];
}
/* ... */
}
因此,在这种特殊情况下,您可以以自由意识使用
ElementAt
。