【问题标题】:How to split List but keep groupBy如何拆分列表但保留 groupBy
【发布时间】:2013-11-15 22:30:26
【问题描述】:

我有以下形式的键/值对列表:

[{John:6},{Alex:100},{Peter:4},{Peter,John:5},{Alex,Kati:1}]

我想知道是否有一个简单的 linq 表达式可以用来将列表翻译成

[{John:11},{Alex:101},{Peter:9},{Kati:1}]

即用逗号分割字符串并调整计数。

以上列表来自以下 LINQ

var list = people.Where(a => !string.IsNullOrWhiteSpace(a.Name))
.GroupBy(a => a.Name.Trim()).Select(a => new User { Name = a.Key, Items= a.Count() });

【问题讨论】:

  • John: 6John:11
  • 是的,John:11 已解决问题
  • 第一个列表似乎不是您拥有的 linq 的输出。您的 linq 的输出将是 {Name = "John", Items = 6} 等的可枚举列表,而不是 {John:6}。你的意思是你有第一个字符串格式的列表,你想解析它并生成第二个列表作为输出字符串?
  • Person.Name 属性是否包含名称列表或为什么键中有逗号?
  • @ShitalShah 是的,名称/计数我试图简化以达到重点。为了更持久,我有 IEnumberable 用户有两个字段名称和计数。

标签: c# linq split


【解决方案1】:

var list = new[]
{
    new KeyValuePair<string, int>("John", 6),
    new KeyValuePair<string, int>("Alex", 100),
    new KeyValuePair<string, int>("Peter", 4),
    new KeyValuePair<string, int>("Peter,John", 5),
    new KeyValuePair<string, int>("Alex,Kati", 1)
};

这个分组

var modifiedList = list.SelectMany(p => p.Key.Split(',').Select(n => new {Name = n, Number = p.Value}))
    .GroupBy(p => p.Name).Select(g => new KeyValuePair<string, int>(g.Key, g.Sum(r => r.Number)));

给你输出

{[John, 11]}
{[Alex, 101]}
{[Peter, 9]}
{[Kati, 1]}

【讨论】:

    【解决方案2】:

    试试这个:

    var list = new List<KeyValuePair<string, int>>
            {
                new KeyValuePair<string,int>("John", 6),
                new KeyValuePair<string,int>("Alex", 100),
                new KeyValuePair<string,int>("Peter", 4),
                new KeyValuePair<string,int>("Peter,John", 5),
                new KeyValuePair<string,int>("Alex,Kati", 1)                
            };
    var result = list.SelectMany(x => x.Key.Split(','),
                                        (x, y) => new KeyValuePair<string, int>(y, x.Value))
                     .GroupBy(x => x.Key)
                     .ToDictionary(key => key.Key, value => value.Sum(x => x.Value));                             
    

    【讨论】:

      【解决方案3】:
      Dictionary<string, int> result = keyVals
          .SelectMany(kv =>  kv.Key.Split(',').Select(name => new{ name, kv.Value }))
          .GroupBy(x => x.name)
          .ToDictionary(xg => xg.Key, xg => xg.Sum(x => x.Value));
      

      结果:

      {[John, 11]}     
      {[Alex, 101]}   
      {[Peter, 9]}    
      {[Kati, 1]}  
      

      Demo

      【讨论】:

        【解决方案4】:

        所以你有这样的课程

        public class Person
        {
            public string Name { get; set; }
        }
        public class User
        {
            public string Name { get; set; }
            public int Items { get; set; }
        }
        

        如果我理解正确,您想计算每个名称出现的次数

        var people = new[]
        {
            new Person { Name = "John" },
            new Person { Name = "John,Alex" },
            new Person { Name = "Alex" },
            new Person { Name  ="Peter,John" }
        };
        
        var list = people.SelectMany(p => p.Name.Split(','))
            .GroupBy(n => n)
            .Select(g => new User { Name = g.Key, Items = g.Count() });
        

        【讨论】:

        • 问题是这并没有像其他解决方案那样将数字相加。它将给约翰:2,亚历克斯:2,彼得:1,卡蒂:1。
        • @RobLyndon 这不是如何从已计算的临时序列(列表)中计算的解决方案。这是根据原始来源(人)计算的。
        • 但这不是我们要求的。
        • @RobLyndon 不是,而是根据问题中提供的信息,这就是用户想要实现的目标。这将删除临时列表并一步计算,而不是两步。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-05-10
        • 1970-01-01
        • 2021-07-14
        • 2017-12-24
        相关资源
        最近更新 更多