【发布时间】:2018-05-02 11:55:15
【问题描述】:
我有下表作为我的输入。
+--------+---------+-------+
| Name | Course | Score |
+--------+---------+-------+
| John | Math | 5 |
| Hannah | Math | 4 |
| Lilly | Math | 5 |
| John | Science | 5 |
| Hannah | Science | 5 |
| Lilly | Science | 5 |
| John | Social | 5 |
| Hannah | Social | 4 |
| Lilly | Social | 3 |
+--------+---------+-------+
作为输出,我想要一个表格来显示姓名、总分、平均分和星级。星星将是学生得分 5/5 的次数。例如,John 应该有 3 星,而 Hannah 应该有 1 星,而 Lilly 应该有 2 星。基本上,我希望将下表作为我的输出:
+--------+-------+---------+------+
| Name | Score | Average | Star |
+--------+-------+---------+------+
| John | 15 | 5 | 3 |
| Hannah | 13 | 4.3 | 1 |
| Lilly | 13 | 4.3 | 2 |
+--------+-------+---------+------+
我能够得到分数和平均分,但我就是不知道如何做星星部分。以编程方式,我认为我需要按名称分组,然后计算重复的数字,我认为应该在 linq 中完成,但我不知道该怎么做:
这是我的代码:
public string Name { get; private set; }
public int Score { get; set; }
public decimal Average { get; set; }
public decimal Count { get; set; }
public Person(string name, int score, decimal avg, int count)
{
Name = name;
Score = score;
Average = avg;
Count = count;
}
public ObservableCollection<Person> Persons { get; set; }
filepath = scoresFile;
public MainWindow()
{
InitializeComponent();
LoadTable();
}
private void datagrid_Sorting(object sender, DataGridSortingEventArgs e)
{
if (e.Column.Header.Equals("Name") || e.Column.Header.Equals("Score"))
{
e.Handled = true;
}
}
public void LoadTable()
{
var lines = File.ReadAllLines(filepath);
Persons = new ObservableCollection<Person>();
var data = lines.Select(line =>
{
var column = line.Split(',');
int c = column[1].Count();
var name = column[1];
int score = int.Parse(column[3]);
decimal avg = decimal.Parse(column[3]);
int count = 0;
return new { name, score, avg, count};
}
);
var groupedData = data.GroupBy(p => p.name)
.Select((g, i) => new {
num= 0, name = g.Key,
score = g.Sum(p => p.score),
avg = decimal.Round(g.Average(p => p.avg), 1),
count = g.Count() })
.OrderByDescending(x => x.avg);
var persons = groupedData.Select((p, i) => new Person(i + 1, p.name, p.score, p.avg, p.count));
foreach (var person in persons)
{
Persons.Add(person);
}
datagrid.ItemsSource = Persons;
}
我一直在尝试对 linq 行进行一些修改,但我认为这不是一个好主意:
var groupedData = data.GroupBy(p => p.name, s=> s.score )
.Where(p => p.Count() > 5).Select((g, i) => new {
num= 0,
name = g.Key,
rank = i + 1,
score = g.Sum(p => p.score),
avg = decimal.Round(g.Average(p => p.avg), 1),
count = g.Count() })
.OrderByDescending(x => x.avg);
然后我想添加以下行并调用 num,但这也没有用。
var num = data.GroupBy(p => p.name, p =p.score).Any(g => g.Count() > 1);
有什么想法吗?
【问题讨论】:
-
Count接受谓词,因此将其更改为count = g.Count(p => p.Score == 5)。完整代码为var groupedData = data.GroupBy(p => p.name).Select((g, i) => new { num= 0, name = g.Key, score = g.Sum(p => p.score), avg = decimal.Round(g.Average(p => p.avg), 1), count = g.Count(p => p.Score == 5) }).OrderByDescending(x => x.avg); -
让我知道答案是否适合您
-
这对你有用吗???
-
@PranayRana 您的解决方案解决了我的问题,非常感谢! :) 我想知道您是否知道是否可以在 LINQ 行中添加 if 语句?例如,如果等于 5 的分数计数为 3,则打印“Excellent”,如果它是 2,则打印“good”等等。你知道这是否可行吗?再次感谢:)
-
@Dr.Bake - 更新了我的答案,请尝试一下,如果对你有用,请接受