我在List<Players>
中填充了Player
个对象,如下所示:
class Player
{
public string Name
{ get; set; }
public int Points
{ get; set; }
public string Rank
{ get; set; }
}
基于Points
,我想获得一个这样的分组排序列表:
Rank Name Points
1-3. RRR 10
CCC 10
AAA 10
4-5. YYY 8
XXX 8
6. ZZZ 7
7-8. UUU 5
QQQ 5
...等等。因此Name
不应是排序的必需项。
LINQ有可能吗?
编辑1:
到目前为止,我已经尝试过:
players.ForEach(x =>
{
int cnt = players.Count(y => y.Points == x.Points);
int ind = players.FindIndex(y => y.Points == x.Points);
x.Rank = (cnt == 1 ? (ind + 1).ToString() : (ind + 1).ToString() + "-" + (ind + cnt).ToString()) + ".";
});
这非常混乱,并且期望的结果不是我想要的。得分等于或高于上述分数的每个玩家都应拥有Rank
属性empty
。
编辑2:
更干净的代码可以达到所需的结果,如下所示:
players.ForEach(x =>
{
int cnt = players.Count(y => y.Points == x.Points);
int ind = players.FindIndex(y => y.Points == x.Points);
x.Rank = ind != players.IndexOf(x) ? string.Empty : $"{ind + 1}" + (cnt == 1 ? string.Empty : "-" + $"{ind + cnt}") + ".";
});
答案 0 :(得分:1)
尝试以下操作:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication106
{
class Program
{
static void Main(string[] args)
{
List<Player> players = new List<Player>() {
new Player() { Name = "RRR", Points = 10 },
new Player() { Name = "CCC", Points = 10 },
new Player() { Name = "AAA", Points = 10 },
new Player() { Name = "YYY", Points = 8 },
new Player() { Name = "XXX", Points = 8 },
new Player() { Name = "ZZZ", Points = 7 },
new Player() { Name = "UUU", Points = 5 },
new Player() { Name = "QQQ", Points = 5 }
};
var groups = players.OrderBy(x => x.Points)
.Select((x, i) => new { rank = i + 1, player = x })
.GroupBy(x => x.player.Points).Select(x => new { rank = x.Min(y => y.rank).ToString() + "-" + x.Max(y => y.rank).ToString(), players = x.ToList()})
.ToList();
foreach (var group in groups)
{
group.players.First().player.Rank = group.rank;
//foreach (var player in group.players)
//{
// player.player.Rank = group.rank;
//}
}
}
}
class Player
{
public string Name
{ get; set; }
public int Points
{ get; set; }
public string Rank
{ get; set; }
}
}
答案 1 :(得分:0)
由于您已经编辑了帖子并显示了解决问题的尝试,因此我们将为您提供帮助。将任何玩家集合传递到此功能中,以按照您要求的格式重新获得玩家的新集合。
注意:此函数修改传入的Player
中的IEnumerable<Player>
引用。如果由于某种原因您不希望这种行为,只需将Player = player
替换为Player = new Player { Name = player.Name, Points = player.Points }
复制它们。
using System;
using System.Linq;
using System.Collections.Generic;
public static IEnumerable<Player> GetGroupedPlayers(IEnumerable<Player> players)
{
return players
.OrderByDescending(player => player.Points)
.Select((player, index) =>
new
{
Player = player,
Rank = ++index
})
.GroupBy(container => container.Player.Points)
.Select(group =>
{
var firstPlayer = group.First().Player;
var groupMin = group.Min(container => container.Rank);
var groupMax = group.Max(container => container.Rank);
firstPlayer.Rank = groupMin == groupMax ? $"{groupMin}." : $"{groupMin} - {groupMax}.";
return group.Select(g => g.Player);
})
.SelectMany(player => player);
}
希望有帮助。