C#排序一个包含数字的字符串列表

7

我是一个正在创建读写文本文件的评分系统。我的当前格式是读取文件的每一行,并将每一行存储到一个List<string>中。一个典型的行可能是这样的:50:詹姆斯(50是分数,詹姆斯是用户名)

我需要按得分排序列表,同时保留名称与字符串。以下是我所说的一个例子:

无序文本文件:

50:James
23:Jessica
70:Ricky
70:Dodger
50:Eric

请注意,有一些分数是相同的,这会妨碍我使用数字键创建列表。

有序列表:

70:Dodger
70:Ricky
50:Eric
50:James
23:Jessica

我的当前代码(不能处理两个或更多相同的分数)

Dictionary<int, string> scoreLines = new Dictionary<int, string>();

if (!File.Exists(scorePath))
{
    File.WriteAllText(scorePath, "No Scores", System.Text.Encoding.ASCII);
}

StreamReader streamReader = new StreamReader(resourcePath + "\\scoreboard.txt");

int failedLines = 0;

while (failedLines < 3)
{
    string line = streamReader.ReadLine();

    if (String.IsNullOrEmpty(line))
    {
        failedLines++;
        continue;
    }

    scoreLines.Add(int.Parse(line.Split(':')[0]), line.Split(':')[1]);
}

var arr = scoreLines.Keys.ToArray();
arr = (from a in arr orderby a descending select a).ToArray();

List<string> sortedScoreLines = new List<string>();

foreach (int keyNum in arr)
{
    sortedScoreLines.Add(keyNum + ":" + scoreLines[keyNum]);
}

return sortedScoreLines;

是的,我知道这个方法非常低效和丑陋,但我花费了很长时间尝试许多不同的方法。

5个回答

19
您可以使用 String.Split:
var ordered = list.Select(s => new { Str = s, Split = s.Split(':') })
            .OrderByDescending(x => int.Parse(x.Split[0]))
            .ThenBy(x => x.Split[1])
            .Select(x => x.Str)
            .ToList();

编辑: 这里有一个使用您的数据在Ideone上的演示: http://ideone.com/gtRYO7


1
考虑添加一个正在发生的事情的解释。我非常怀疑原帖作者理解这段代码。 - evanmcdonnal
它完美地运行了,非常感谢!诚然,我不太理解它,但我会进行一些研究! - André
@user1363526:你不理解的部分是什么?我看到了你的linq查询,所以我没有添加解释。 - Tim Schmelter
没关系,只是有些术语让我有点困惑。再次感谢你的帮助! - André
@user1363526:可能是匿名类型的第一行。我使用它来避免两次拆分字符串。 - Tim Schmelter

3
已经有许多好的答案了。我只想提供一个更短的版本:
List<string> ordered = list.OrderByDescending(s => int.Parse(Regex.Match(s, @"\d+").Value)).ToList();

(当然,这假定您的项中除了开头的数字以外没有其他数字)

3
你可以使用ReadAllLines方法轻松读取文件,然后使用OrderByDescending按从解析的值排序字符串:
string[] sortedScoreLines =
  File.ReadAllLines(resourcePath + "\\scoreboard.txt")
  .OrderByDescending(s => Int32.Parse(s.Substring(0, s.IndexOf(':'))))
  .ThenBy(s => s)
  .ToArray();

1
基于Guffa的答案,加上一些注释。
string[] sortedScoreLines =
            File.ReadAllLines(resourcePath + "\\scoreboard.txt");

        // parse into an anonymous class
        var parsedPersons = from s in sortedScoreLines
                            select new
                                       {
                                           Score = int.Parse(s.Split(':')[0]),
                                           Name = s.Split(':')[1]
                                       };

        // sort the list
        var sortedPersons = parsedPersons.OrderByDescending(o => o.Score).ThenBy(i => i.Name);

        // rebuild the resulting array
        var result = (from s in sortedPersons
                     select s.Score + ":" + s.Name).ToArray();

0

请检查:

var sortedScoreLines = GetLines("inputFilePath")
        .Select(p => new { num = int.Parse(p.Split(':')[0]), name = p.Split(':')[1] })
        .OrderBy(p => p.num)
        .ThenBy(p => p.name)
        .Select(p => string.Format("{0}:{1}", p.num, p.name))
        .ToList();

    private static List<string> GetLines(string inputFile)
    {
        string filePath = Path.Combine(Directory.GetCurrentDirectory(), inputFile);
        return File.ReadLines(filePath).ToList();
    }

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