从列表中获取前五个分数/名称。

3
我正在为我制作的小游戏添加一个跟踪分数的函数。我想从包含得分的文件中获取前五个得分(包括该得分对应的姓名)。
保存得分的格式为:
[name]-[score]
得分和姓名存储在两个列表中,我是这样解析它们的:
string scores = File.ReadAllText(Environment.GetEnvironmentVariable("TEMP") + "/scores");
string[] splitscores = scores.Split('\n');

foreach (string entry in splitscores)
{
    string replace = entry.Replace("[", "").Replace("]", "");
    string[] splitentry = replace.Split('-');

    if (splitentry.Count() > 1)
    {
        scorenames.Add(splitentry[0]);
        scorelist.Add(Int32.Parse(splitentry[1]));
    }
}

然后我使用以下代码来检索排名第一的玩家:
int indexMax
    = !scorelist.Any() ? -1 :
    scorelist
    .Select((value, index) => new { Value = value, Index = index })
    .Aggregate((a, b) => (a.Value > b.Value) ? a : b)
    .Index;

lblhighscore1.Text = "#1:  " + scorelist[indexMax] + " by " + scorenames[indexMax];

如果这是我的得分列表,我该如何设置剩下的4个玩家:

[broodplank]-[12240]
[flo]-[10944]
[bill]-[11456]
[tony]-[9900]
[benji]-[7562]

我想对得分列表进行降序排序,但这不会涵盖用户名列表索引的变化,针对此情况最好的方法是什么?


你可以尝试使用ReadAllLines代替ReadAllText/.Split - crashmstr
2个回答

9

最佳方案?不要使用并行集合反模式

取而代之的是,创建一个可以同时保存名称和分数的类,而不是拥有两个列表。

class Score
{
    public string Name { get; private set; }
    public int Score { get; private set; }

    public Score(string name, int score)
    {
        Name = name;
        Score = score;
    }
}

并且只有一个列表。
List<Score> scores = new List<Score>();

foreach (string entry in splitscores)
{
    string replace = entry.Replace("[", "").Replace("]", "");
    string[] splitentry = replace.Split('-');

    if (splitentry.Count() > 1)
    {
        scores.Add(new Score(splitentry[0], Int32.Parse(splitentry[1]))
    }
}

您可以轻松地按一个属性进行排序,因为整个对象将被重新排序,所以您将保持名称的正确顺序,而无需任何其他代码:
topScores = scores.OrderByDescending(x => x.Score).Take(5);

0
除了MarcinJuraszeks有用的答案之外,我还遇到了一些小问题,决定分享一下。
第一个问题是与抛出以下错误的类有关:
“Score”:成员名称不能与其封闭类型相同
更改“s”的大小写即可解决它。
class Score
{
    public string Name { get; private set; }
    public int score { get; private set; }

    public Score(string name, int Score)
    {
        Name = name;
        score = Score;
    }
}

使用Linq可以调用单个值

string numberOne = topScores.Skip(0).First().score
string numberTwo = topScores.Skip(1).First().score 

等等


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接