2011-03-19 60 views
0

我需要使用IGrouping實現它的對象,但我不記得哪個集合是iGrouping。哪個是.net中的IGrouping集合?

例子我想要做的:

var grouper = new Grouper<string,string>(); 
grouper.Add("car","ford"); 
grouper.Add("car","mercedes"); 
string[] cars = grouper["car"]; // cars = {"ford","mercedes"}; 

石斑魚是啞類在這裏

+1

可以通過密鑰將對象分組,如本字典<字符串列表>但分組字典將比此更簡單。 – Freshblood 2011-03-19 14:19:40

回答

3

Enumerable.ToLookup()返回IGrouping的(一個ILookup)的集合 - 如果這就是你要找的人。

MSDN sample

class Package 
{ 
    public string Company { get; set; } 
    public double Weight { get; set; } 
    public long TrackingNumber { get; set; } 
} 

public static void ToLookupEx1() 
{ 
    // Create a list of Packages. 
    List<Package> packages = 
     new List<Package> 
      { new Package { Company = "Coho Vineyard", 
        Weight = 25.2, TrackingNumber = 89453312L }, 
       new Package { Company = "Lucerne Publishing", 
        Weight = 18.7, TrackingNumber = 89112755L }, 
       new Package { Company = "Wingtip Toys", 
        Weight = 6.0, TrackingNumber = 299456122L }, 
       new Package { Company = "Contoso Pharmaceuticals", 
        Weight = 9.3, TrackingNumber = 670053128L }, 
       new Package { Company = "Wide World Importers", 
        Weight = 33.8, TrackingNumber = 4665518773L } }; 

    // Create a Lookup to organize the packages. 
    // Use the first character of Company as the key value. 
    // Select Company appended to TrackingNumber 
    // as the element values of the Lookup. 
    ILookup<char, string> lookup = 
     packages 
     .ToLookup(p => Convert.ToChar(p.Company.Substring(0, 1)), 
        p => p.Company + " " + p.TrackingNumber); 

    // Iterate through each IGrouping in the Lookup. 
    foreach (IGrouping<char, string> packageGroup in lookup) 
    { 
     // Print the key value of the IGrouping. 
     Console.WriteLine(packageGroup.Key); 
     // Iterate through each value in the 
     // IGrouping and print its value. 
     foreach (string str in packageGroup) 
      Console.WriteLine(" {0}", str); 
    } 
} 
1

看來你需要一個ILookup<TK,TV>實現,但不幸被ToLookup() LINQ方法中使用的是不公開的。

反正是很容易實現(特別是如果有人像Jon Skeet already did

public sealed class Lookup<TKey, TElement> : ILookup<TKey, TElement> 
{ 
    private readonly Dictionary<TKey, List<TElement>> map; 
    private readonly List<TKey> keys; 

    public Lookup() 
     : this(EqualityComparer<TKey>.Default) 
    { } 

    public Lookup(IEqualityComparer<TKey> comparer) 
    { 
     map = new Dictionary<TKey, List<TElement>>(comparer); 
     keys = new List<TKey>(); 
    } 

    public void Add(TKey key, TElement element) 
    { 
     List<TElement> list; 
     if (!map.TryGetValue(key, out list)) 
     { 
      list = new List<TElement>(); 
      map[key] = list; 
      keys.Add(key); 
     } 
     list.Add(element); 
    } 

    public int Count 
    { 
     get { return map.Count; } 
    } 

    public IEnumerable<TElement> this[TKey key] 
    { 
     get 
     { 
      List<TElement> list; 
      if (!map.TryGetValue(key, out list)) 
      { 
       return Enumerable.Empty<TElement>(); 
      } 
      return list.Select(x => x); 
     } 
    } 

    public bool Contains(TKey key) 
    { 
     return map.ContainsKey(key); 
    } 

    public IEnumerator<IGrouping<TKey, TElement>> GetEnumerator() 
    { 
     return keys.Select(key => new Grouping<TKey, TElement>(key, map[key])) 
        .GetEnumerator(); 
    } 

    IEnumerator IEnumerable.GetEnumerator() 
    { 
     return GetEnumerator(); 
    } 
} 

public sealed class Grouping<TKey, TElement> : IGrouping<TKey, TElement> 
{ 
    private readonly TKey key; 
    private readonly IEnumerable<TElement> elements; 

    public Grouping(TKey key, IEnumerable<TElement> elements) 
    { 
     this.key = key; 
     this.elements = elements; 
    } 

    public TKey Key { get { return key; } } 

    public IEnumerator<TElement> GetEnumerator() 
    { 
     return elements.GetEnumerator(); 
    } 

    IEnumerator IEnumerable.GetEnumerator() 
    { 
     return GetEnumerator(); 
    } 
} 

用法:

var lookup = new Lookup<string, string>(); 
lookup.Add("car", "ford"); 
lookup.Add("car", "mercedes"); 
var cars = lookup["car"]; 
// cars is an IEnumerable<string> containing {"ford","mercedes"} 

這真的是類似於你的要求,是不是?