2012-11-16 21 views
6

Mam słownik: Dictionary<int,int>. Chcę uzyskać nowy słownik, w którym klucze oryginalnego słownika reprezentują jako List<int>. To, co mam na myśli:Słownik "Grupowanie" według wartości

var prices = new Dictionary<int,int>(); 

prices zawierać następujące dane:

1 100 
2 200 
3 100 
4 300 

Chcę uzyskać IList<Dictionary<int,List<int>>>:

int  List<int> 
100  1,3 
200  2 
300  4 

Jak mogę to zrobić?

Odpowiedz

14
var prices = new Dictionary<int, int>(); 
prices.Add(1, 100); 
prices.Add(2, 200); 
prices.Add(3, 100); 
prices.Add(4, 300); 

Dictionary<int,List<int>> test = 
        prices.GroupBy(r=> r.Value) 
        .ToDictionary(t=> t.Key, t=> t.Select(r=> r.Key).ToList()); 
+0

Dzięki, ale , wartości zawiera wszystkie obiekty, chcę tylko klucze z oryginalnego słownika – user1260827

+0

@ user1260827, przepraszam brakowało jednej rzeczy, możesz spróbować zapytanie teraz. Właśnie wypróbowałem to w VS i jego działaniu – Habib

+0

Dzięki. To jest to, czego potrzebuję. – user1260827

2

Można użyć GroupBy.

Dictionary<int,List<int>> groups = 
      prices.GroupBy(x => x.Value) 
        .ToDictionary(x => x.Key, x => x.Select(i => i.Key).ToList()); 
2

Oto moja odpowiedź. Gdy słowniki stają się duże, najprawdopodobniej metody grupowania w GroupBy() staną się mniej efektywne niż chcesz, ponieważ zapewniają wiele gwarancji, których nie potrzebujesz, takich jak zachowanie zamówienia.

public static class DictionaryExtensions 
{ 
    public static IDictionary<TValue,List<TKey>> Reverse<TKey,TValue>(this IDictionary<TKey,TValue> src) 
    { 
     var result = new Dictionary<TValue,List<TKey>>(); 

     foreach (var pair in src) 
     { 
      List<TKey> keyList; 

      if (!result.TryGetValue(pair.Value, out keyList)) 
      { 
       keyList = new List<TKey>(); 
       result[pair.Value] = keyList; 
      } 

      keyList.Add(pair.Key); 
     } 

     return result; 
    } 
} 

i przykład do wykorzystania w LINQPad:

void Main() 
{ 
    var prices = new Dictionary<int, int>(); 
    prices.Add(1, 100); 
    prices.Add(2, 200); 
    prices.Add(3, 100); 
    prices.Add(4, 300); 

    // Dump method is provided by LinqPad. 
    prices.Reverse().Dump(); 
} 
0

W szczególnym przypadku, gdy używamy systemu .NET Framework 2.0, możemy to zrobić w następujący sposób:

var prices = new Dictionary<int, int>(); 
prices.Add(1, 100); 
prices.Add(2, 200); 
prices.Add(3, 100); 
prices.Add(4, 300); 

Dictionary<int, List<int>> grouping = new Dictionary<int, List<int>>(); 

var enumerator = prices.GetEnumerator(); 
while (enumerator.MoveNext()) 
{ 
    var pair = enumerator.Current; 
    if (!grouping.ContainsKey(pair.Value)) 
     grouping[pair.Value] = new List<int>(); 
    grouping[pair.Value].Add(pair.Key); 
} 
Powiązane problemy