How ToLookup() with multiple indexes?

一个人想着一个人 提交于 2019-12-07 10:14:05

问题


Taking into account the code for C# Console application below, using

how should I modify it in order to substitute the line:

foreach (Product product in productsByCategory[category])

by the code line

foreach (Product product in productsByCategory[category][Id])

?

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace myQuestion
{
  class Program
  {
    static void Main(string[] args)
    {
      var products = new List<Product>
      {
        new Product { Id = 1, Category = "Garden", Value = 15.0 },
        new Product { Id = 1, Category = "Garden", 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 = 21.25 },
        new Product { Id = 7, Category = "Pets", Value = 5.50 },
        new Product { Id = 8, Category = "Garden", Value = 13.0 },
        new Product { Id = 9, Category = "Automotive", Value = 10.0 },
        new Product { Id = 10, Category = "Electronics", Value = 250.0 }
      };


      ILookup<string, Product> productsByCategory = 
              products.ToLookup( p => p.Category);
      string category = "Garden";
      int Id = 1;
      foreach (Product product in productsByCategory[category])
      {
        Console.WriteLine("\t" + product);
      }

      Console.ReadLine();
    }
  }

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

Update:
This is a contrived example with the aim of learning the concepts of C# ToLookup Method.

As a point of reference, I came to this question after reading the David Andres' answer to question "What is the point of Lookup?":

"A Lookup will map to potentially several values.  

Lookup["Smith"]["John"] will be a collection of size one billion."   

which I'd like to reproduce.

Or I understood it wrong?


回答1:


Not sure I understand your needs correctly, but why can't you just do:

foreach (Product product in productsByCategory[category].Where(x=> x.Id == Id))

Or with an anonymous object:

var productsByCategory = products.ToLookup(p => new { p.Category, p.Id });
string category = "Groceries";
int Id = 1;
foreach (Product product in productsByCategory[new {Category = category, Id= Id}])
{
    Console.WriteLine("\t" + product);
}

Here is very similar question with additional solution by Servy




回答2:


I've stumbled upon this question, read "closing it as being confirmed to me that it is impossible" and made a hefty research on the topic. The closest I could get to was this:

Turns out this can't be done because:

  1. There is no constructor for type Lookup<T, T>, one can only use .ToLookup() LINQ extension function,
  2. Said function doesn't have an overload with resultSelector (like .GroupBy() does) and thus always only returns IGrouping<TKey, TElement>.

Even if the result of the lookup is just one element (another Lookup), there is no possibility to omit the first IGrouping. So the call to .Single() (or .First() or .ToList()[0] or .ElementAt(0)) is required after each call to "parent" Lookup, which is... smelly and desperate.

But

The same syntax for accessing elements can be instead achieved with nested Dictionary<T, T>:

LINQPad C# code uploaded here.



来源:https://stackoverflow.com/questions/15734454/how-tolookup-with-multiple-indexes

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!