【问题标题】:"Grouping" dictionary by value按值“分组”字典
【发布时间】:2012-11-16 04:45:04
【问题描述】:

我有一本字典:Dictionary<int,int>。我想获取新字典,其中原始字典的键表示为List<int>。这就是我的意思:

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

prices 包含以下数据:

1   100
2   200
3   100
4   300

我想得到IList&lt;Dictionary&lt;int,List&lt;int&gt;&gt;&gt;

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

我该怎么做?

【问题讨论】:

    标签: c# .net linq dictionary grouping


    【解决方案1】:
    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());
    

    【讨论】:

    • 谢谢,但是,值包含所有对象,我只想要原始字典中的键
    • @user1260827,很抱歉错过了一件事,您现在可以尝试查询。我刚刚在 VS 中尝试过,它的工作原理
    • 谢谢。这就是我需要的。
    • 谁能解释一下“ToDictionary”在这里的作用?
    • @burhan,它创建了一个Dictionary,你可以阅读更多关于Enumerable.ToDictionary的信息
    【解决方案2】:

    您可以使用GroupBy

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

    【讨论】:

      【解决方案3】:

      这是我的回复。当字典变大时,您可能会发现 GroupBy() 扩展方法的效率低于您的预期,因为它们提供了许多您不需要的保证,例如保留顺序。

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

      还有一个在 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();
      }
      

      【讨论】:

        【解决方案4】:

        您可以使用GroupBy 后跟the Func&lt;TSource, TKey&gt;, Func&lt;TSource, TElement&gt; overload of Enumerable.ToDictionary

        var d = prices.GroupBy(x => x.Value).ToDictionary(x => x.Key, x => x.ToList());
        

        【讨论】:

          【解决方案5】:

          您可以改用 Lookup。

          var prices = new Dictionary<int, int> { {1, 100}, { 2, 200 }, { 3, 100 }, { 4, 300 } };
          ILookup<int, int> groups = prices.ToLookup(x => x.Value, y => y.Key);
          foreach (var group in groups)
          {
              foreach (var item in group)
              {
                  Console.WriteLine(item);
              }
          }
          

          【讨论】:

            【解决方案6】:

            在特定情况下,当我们使用 .NET framework 2.0 时,我们可以这样做:

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

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2017-02-24
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多