【问题标题】:Grouping KeyValue pairs to Dictionary将键值对分组到字典
【发布时间】:2011-04-28 00:55:01
【问题描述】:

我有以下代码:

using System.Collections.Generic;


public class Test
{
    static void Main()
    {

        var items = new List<KeyValuePair<int, User>>
                        {
                            new KeyValuePair<int, User>(1, new User {FirstName = "Name1"}),
                            new KeyValuePair<int, User>(1, new User {FirstName = "Name2"}),
                            new KeyValuePair<int, User>(2, new User {FirstName = "Name3"}),
                            new KeyValuePair<int, User>(2, new User {FirstName = "Name4"})
                        };

    }
}
public class User
{
    public string FirstName { get; set; }
}

如您所见,同一个 key 有多个用户。现在我想对它们进行分组并将列表对象转换为字典,其中键将相同(如上所示的 1,2)但值将是集合。像这样:

 var outputNeed = new Dictionary<int, Collection<User>>();
        //Output:
        //1,Collection<User>
        //2,Collection<User>

即他们现在被分组了。

我怎样才能做到这一点?

【问题讨论】:

    标签: c# generics dictionary key-value


    【解决方案1】:

    这是我的解决方案:

    var items = new List<KeyValuePair<int, User>>
    {
        new KeyValuePair<int, User>(1, new User { FirstName = "Name1" }),
        new KeyValuePair<int, User>(1, new User { FirstName = "Name2" }),
        new KeyValuePair<int, User>(2, new User { FirstName = "Name3" }),
        new KeyValuePair<int, User>(2, new User { FirstName = "Name4" })
    };
    
    var result = (
        from item in items
        group item.Value by item.Key into grouped
        select grouped
    ).ToDictionary(g => g.Key, g => g);
    

    DotNetFiddle

    【讨论】:

      【解决方案2】:

      我建议您改用Lookup&lt;TKey, TElement&gt;。此数据结构专门用作从键到值集合的映射。

      //uses Enumerable.ToLookup: the Id is the key, and the User object the value
      var outputNeeded = items.ToLookup(kvp => kvp.Key, kvp => kvp.Value);
      

      当然,如果您确实需要字典(也许允许可变性),您可以执行以下操作:

      var outputNeeded = new Dictionary<int, Collection<User>>();
      
      foreach(var kvp in list)
      {
         Collection<User> userBucketForId;
      
         if(!outputNeeded.TryGetValue(kvp.Key, out userBucketForId)) 
         {
             // bucket doesn't exist, create a new bucket for the Id, containing the user
             outputNeeded.Add(kvp.Key, new Collection<User> { kvp.Value });
         }
         else 
         {   // bucket already exists, append user to it.
             userBucketForId.Add(kvp.Value);
         }
      }
      

      另一方面,Collection&lt;T&gt;class 并不是很有用,除非您打算将其子类化。你确定你不仅仅需要List&lt;User&gt;吗?

      【讨论】:

      • 太棒了!阿尼。只是几个错别字 1.kvp.Key 而不是 kvp.key 2 if(!outputNeeded.TryGetValue(kvp.key, out userBucketForId) 右括号丢失。但解决方案很棒!
      • @Rocky Singh:很高兴为您提供帮助。感谢您指出错别字;固定
      【解决方案3】:

      这是一个使用 LINQ 的 ToDictionary 的示例:

      var output = items.GroupBy(kvp => kvp.Key)
                        .ToDictionary(group => group.Key,
                                      group => group.Select(kvp => kvp.Value).ToList());
      

      结果为@​​987654322@。

      【讨论】:

        【解决方案4】:

        鉴于您的初始变量“item”和建议的输出变量“outputNeed”,您需要这样做:

        注意:这不是实际的 c#/vb 代码,因此请根据需要更改此伪代码(我手头没有 VS Studio):

        foreach (KeyValuePair<int, User> pair in items) 
        {
            //add a new collection if this is the first time you encounter the key
            if (! outputNeed.Contains(pair.Key) 
            {
                outputNeed[pair.Key] = new ArrayList<User>());
            }
            //add the user to the matching collection
            outputNeed.Add(pair.Key, pair.User);
        }
        

        祝你好运

        【讨论】:

          【解决方案5】:
          foreach (var u in items)
          {
              if (outputNeed.Contains(u.Key)) {
                  outputNeed[u.Key].Add(u.Value);
              }
              else {
                  Collection<User> a=new Collection<User>();
                  a.Add(u.Value);
                  outputNeed.Add(u.Key,a);
              }
          }
          

          【讨论】:

            猜你喜欢
            • 2011-04-28
            • 1970-01-01
            • 1970-01-01
            • 2013-08-13
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2017-11-15
            • 1970-01-01
            相关资源
            最近更新 更多