我正在尝试计算对象的排名。由于多个对象可以具有相同的分数,我需要将它们分组,以便它们获得相同的排名。
public class RankedItem {
public string Name {get; set;}
public int Score {get; set; }
public int Rank {get; set; }
public RankedItem(string name, int score) {
Name = name;
Score = score;
}
}
public void CalculateRanks() {
List<RankedItem> items = new List<RankedItems> {
new RankedItem("A", 3),
new RankedItem("B", 2),
new RankedItem("C", 3),
new RankedItem("D", 1),
new RankedItem("E", 2)
};
IOrderedEnumerable<IGrouping<int, RankedItems>> rankedItems = items.GroupBy(i => b.Score).OrderBy(g => g.Key);
}
现在如何设置排名,以便将排名1
分配给最高分?
最佳答案
这里基本上有两个选择。 Linq 或循环。对于这两个选项,您应该使用OrderByDescending
,因为您的分数排名关系是相反的。然后你可以使用索引+1来分配排名。
- 循环。
对于此选项,您需要一个集合来保存可以使用索引 [ ]
运算符进行迭代的分组。这在 IOrderedEnumerable 中是不可能的。所以我建议使用 List
:
List<IGrouping<int, RankedItem>> rankedItems = items.GroupBy(b => b.Score)
.OrderByDescending(g => g.Key)
.ToList();
现在,您可以简单地循环遍历具有索引的列表,然后再次循环遍历每个组的所有元素,以使用索引来分配排名:
for (int i = 0; i < rankedItems.Count(); i++)
{
IGrouping<int, RankedItem> grouping = rankedItems[i];
foreach (var element in grouping)
{
element.Rank = i + 1;
}
}
- LINQ:
使用此Select中的索引重载语句并使用构造函数创建新对象:
List<RankedItem> rankedItems = items.GroupBy(b => b.Score)
.OrderByDescending(g => g.Key)
.SelectMany((item, index) => item.Select(inner =>
new RankedItem(inner.Name, item.Key) {Rank = index + 1})
).ToList();
结果:
关于c# - Linq 用于使用 group 和 orderby 计算排名,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65179665/