我有一个目前属于结构的数据表
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
有两列而不是三列。
提前致谢
答案 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
添加行。请记住,必须有很多方法来做同样的事情。