LINQ on datatable,group,sum和get逗号分隔的字符串C#

时间:2017-01-13 08:27:51

标签: c# linq

我有一个目前属于结构的数据表

Index | Player | Score
a     |  abby  |   1
z     |  bob   |   5
f     |  abby  |   4
p     |  bob   |   3

我想通过Linq中的播放器对数据表进行分组,以便它将索引列提供为逗号分隔的字符串,并将该播放器的得分列相加,并将结果作为数据表返回。

例如,上面应该最终会像。

Index | Player | Score
a,f   |  abby  |   5   
z,p   |  bob   |   8

遗憾的是,我不知道如何做到这一点,我只能找到关于如何执行sum组件的示例,但其中一些似乎只适用于datatable有两列而不是三列。

提前致谢

4 个答案:

答案 0 :(得分:3)

您可以使用此查询简单地获取它:

- 使用string.Join() - 获取包含每个用户索引的扁平数组

- 使用GroupBy() - 按玩家名称获取

- 使用Sum() - 获得每位玩家的总分

var data = new[]
    {
      new Foo {Index = "a", Player = "abby", Score = 1},
      new Foo {Index = "z", Player = "bob", Score = 5},
      new Foo {Index = "f", Player = "abby", Score = 4},
      new Foo {Index = "p", Player = "bob", Score = 3},
    };

var result = data.GroupBy(l => l.Player)
             .Select(cl => new Foo()
             {
                Index = string.Join(", ", data.Where(d => d.Player == cl.Key).Select(d => d.Index).ToArray()),
                Player = cl.Key,
                Score = cl.Sum(c => c.Score)
             }).ToList();

答案 1 :(得分:0)

var groupedData = ctx.TableName.GroupBy(x => x.Player).Select(x => new TableName
{
    Player = x.Key,
    Score = x.Sum(y => y.Score),
    Index = string.Join(",", x.Select(y => y.Index).ToArray())
});

答案 2 :(得分:0)

应该让你更近一点:

private class SwingFileChooser extends JFileChooser {
  private FileNameExtensionFilter filter;
  protected void chooseFiles() {
    filter = new FileNameExtensionFilter("(*.java)", "java");
    this.setFileFilter(filter);
    this.setCurrentDirectory(new File(System.getProperty("user.dir")));
    this.setAcceptAllFileFilterUsed(false);
    int returnVal = this.showOpenDialog(rootPane);
    if (returnVal == JFileChooser.APPROVE_OPTION) {
      String file = this.getSelectedFile().getName();
      System.out.println("You choose the file: " + file);
    }
  }
}

答案 3 :(得分:0)

首先,您必须按Player分组。然后,您只需使用String.Join为索引选择新字段,并为分数选择Sum

var result = dt.AsEnumerable()
    .GroupBy(x => x.Field<string>("Player"))
    .Select(y=> new { 
                Index=String.Join(",", y.Select(z => z.Field<string>("Index"))),
                Player=y.Key,
                Score=y.Sum(sc=>sc.Field<int>("Score")) 
                }
            );

修改

我刚看到你想把结果作为DataTable。你可以这样做:

DataTable dtResult=dtOriginal.Clone();
dtOriginal.AsEnumerable()
           .GroupBy(x => x.Field<string>("Player"))
           .Select(y=> new {  
                            Index=String.Join(",", y.Select(z => z.Field<string>("Index"))),
                            Player=y.Key, 
                            Score=y.Sum(sc=>sc.Field<int>("Score"))
                            })
           .ToList()
           .ForEach(i => {dtResult.Rows.Add(i.Index, i.Player, i.Score);});

与这里的所有答案大致相同。我们只是将结果复制到列表中,然后使用ForEach添加行。请记住,必须有很多方法来做同样的事情。