C# ToLookup():按数字索引访问组/项?
我有以下产品清单C# ToLookup():按数字索引访问组/项?,c#,linq,C#,Linq,我有以下产品清单 public sealed class Product { public int Id { get; set; } public string Category { get; set; } public double Value { get; set; } public override string ToString() { return string.Format("[{0}: {1} - {2}]", Id, Ca
public sealed class Product
{
public int Id { get; set; }
public string Category { get; set; }
public double Value { get; set; }
public override string ToString()
{
return string.Format("[{0}: {1} - {2}]", Id, Category, Value);
}
}
var products = new List<Product>
{
new Product { Id = 1, Category = "Electronics", Value = 15.0 },
new Product { Id = 2, Category = "Groceries", Value = 40.0 },
new Product { Id = 3, Category = "Garden", Value = 210.3 },
new Product { Id = 4, Category = "Pets", Value = 2.1 },
new Product { Id = 5, Category = "Electronics", Value = 19.95 },
new Product { Id = 6, Category = "Pets", Value = 5.50 },
new Product { Id = 7, Category = "Electronics", Value = 250.0 },
};
现在我想从中得到一些信息:
// get the number of categories/groups
Console.WriteLine(productLookup.Count());
// FAILS: get the number of items in the second category
Console.WriteLine(productLookup[2].Count());
// FAILS: get a certain item by numeric index (1: group | 3: item in group)
Console.WriteLine(productLookup[1][3]);
我必须使用数字索引,不能使用类别字符串,除非我会创建另一个包含所有键的结构
GroupBy()。它给你一个索引
Console.WriteLine(productLookup.ToList()[2].Count())
ILookup
没有根据索引获取元素的索引器,但它有一个索引器,用于获取由案例类别中指定键索引的值序列
public interface ILookup<TKey, TElement> : IEnumerable<IGrouping<TKey, TElement>>, IEnumerable
{
// Summary:
// Gets the System.Collections.Generic.IEnumerable<T> sequence of values indexed
// by a specified key.
//
// Parameters:
// key:
// The key of the desired sequence of values.
//
// Returns:
// The System.Collections.Generic.IEnumerable<T> sequence of values indexed
// by the specified key.
IEnumerable<TElement> this[TKey key] { get; }
}
由ToLookup
方法生成的ILookup
是一种字典数据结构,因此它用于通过键进行有效搜索。它不自然地提供索引访问(这同样适用于字典
)。当然,由于ILookup
是IEnumerable
和IGrouping
是IEnumerable
,因此可以使用来模拟这样的索引访问
Console.WriteLine(productLookup.ElementAt(2).Count());
Console.WriteLine(productLookup.ElementAt(1).ElementAt(3));
但这是不自然的
如果您只需要索引访问,那么以下内容可能更合适:
var productList = products.GroupBy(p => p.Category)
.Select(g => new { Key = g.Key, Elements = g.ToList() })
.ToList();
Console.WriteLine(productList.Count);
Console.WriteLine(productList[2].Elements.Count);
Console.WriteLine(productList[1].Elements[3]);
我看不出你为什么不这么做:
var productLookup = products.ToLookup(p => p.Category).Select(x => x.ToArray()).ToArray();
productLookup
的类型现在只是Product[][]
然后,代码运行正常(一旦使用了有效的数组索引值):
这给了我:
请注意,一旦有了数组,最好使用Length
@Aravol-不,不是真的。因为数组实现了ICollection
,所以它只调用.Count
,而不迭代元素。有趣的是,它在参考源上得到了确认。请注意,数组实现的是ICollection
,而不是ICollection
,但调用Count()
@Aravol时,最终结果是相同的-是的,我在源代码上进行了检查。阵列也实现了ICollection
。以下是int
数组的完整列表-ICloneable
,ICollection
,ICollection
,IEnumerable
,IEnumerable
,IList
,IReadOnlyCollection
,IReadOnlyList
,iStructuralCompatible
,IStructuralEquatable
。
var productList = products.GroupBy(p => p.Category)
.Select(g => new { Key = g.Key, Elements = g.ToList() })
.ToList();
Console.WriteLine(productList.Count);
Console.WriteLine(productList[2].Elements.Count);
Console.WriteLine(productList[1].Elements[3]);
var productLookup = products.ToLookup(p => p.Category).Select(x => x.ToArray()).ToArray();
Console.WriteLine(productLookup.Count());
Console.WriteLine(productLookup[2].Count());
Console.WriteLine(productLookup[0][2]);