如果玩家“飞行”超出评分(例如,排名第六),我需要将其从词典和文件中删除。 我有一个主意,可以通过Dictionary.Remove,然后将其覆盖在文件中。
我制定了一个动作算法: 读取文件,删除内存中的行,然后将内容返回文件(覆盖)。如果文件很大,您可以阅读该行的内容并创建一个临时文件,稍后再替换原始文件。
以下是将它们分类到位的代码,也许有些帮助:
private static Dictionary<string, int> AllNames()
{
return File
.ReadLines(@"C:\Users\HP\Desktop\картинки\results.txt")
.Where(line => !string.IsNullOrWhiteSpace(line))
.Select(item => item.Split(' '))
.ToDictionary(items => items[0],
items => int.Parse(items[1]));
}
private void updateRatingLabels()
{
var tops = AllNames()
.OrderBy(pair => pair.Value)
.ThenBy(pair => pair.Key, StringComparer.Ordinal)
.Take(5)
.ToArray();
for (int i = 18; i <= 22; ++i)
Controls.Find($"label{i}", true).First().Text = "";
for (int i = 28; i <= 32; ++i)
Controls.Find($"label{i}", true).First().Text = "";
for (int i = 0; i < tops.Length; ++i)
{
Controls.Find($"label{i + 18}", true).First().Text = tops[i].Key;
Controls.Find($"label{i + 28}", true).First().Text = $"{tops[i].Value / 60}:{tops[i].Value % 60:00}";
}
}
答案 0 :(得分:1)
Let's put the question in a different way: we are going keep (not remove) at most 5
top players. We have to consider what we should do in case of tie (i.e. 2
or more players have the same score). I think it'll be honest to keep all such players (so that the actual dictionary can be longer than 5
records):
var newDictionary = AllNames()
.GroupBy(pair => pair.Value) // groups by scores
.OrderBy(chunk => chunk.Key) // less seconds the better
.Take(5) // at most 5 groups (ties preserved)
.SelectMany(chunk => chunk) // flatten back ("ungroup")
.ToDictionary(pair => pair.Key,
pair => pair.Value);
To save the data into the file, try File.WriteAllLines
; let's use "Name Value"
format
File.WriteAllLines(@"c:\TopPlayers.txt", newDictionary
.Select(pair => $"{pair.Key} {pair.Value}"));
Edit: If we have to add an user, with name
and score
we can do it in 2
ways:
Whatever score
is remove 5
th place and add new user:
var newDictionary = AllNames()
.GroupBy(pair => pair.Value) // groups by scores
.OrderBy(chunk => chunk.Key) // less seconds the better
.Take(4) // at most 4 groups (ties preserved)
.SelectMany(chunk => chunk) // flatten back ("ungroup")
.ToDictionary(pair => pair.Key,
pair => pair.Value);
newDictionary.Add(name, score);
Add new user, then take top 5
(note, that new user can be excluded as a lower performer)
var newDictionary = AllNames()
.Concat(new KeyValuePair<string, int>[] {
new KeyValuePair<string, int>(name, score)} // All new users here
)
.GroupBy(pair => pair.Value) // groups by scores
.OrderBy(chunk => chunk.Key) // less seconds the better
.Take(5) // at most 5 groups (ties preserved)
.SelectMany(chunk => chunk) // flatten back ("ungroup")
.ToDictionary(pair => pair.Key,
pair => pair.Value);
Edit 2: So you can implement a method like
private void SaveNewUser(string name, int score) {
var newDictionary = AllNames()
.GroupBy(pair => pair.Value) // groups by scores
.OrderBy(chunk => chunk.Key) // less seconds the better
.Take(4) // at most 4 groups (ties preserved)
.SelectMany(chunk => chunk) // flatten back ("ungroup")
.ToDictionary(pair => pair.Key,
pair => pair.Value);
newDictionary.Add(name, score);
File.WriteAllLines(@"c:\TopPlayers.txt", newDictionary
.Select(pair => $"{pair.Key} {pair.Value}"));
}
which you can call somewhere on, say, a button click:
private void saveButton_Click(object sender, EventArgs e) {
SaveNewUser(textBoxWithName.Text, int.Parse(textBoxWithScore.Text));
}