Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# ToLookup():按数字索引访问组/项?_C#_Linq - Fatal编程技术网

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]);