简体   繁体   English

C#对包含数字的字符串列表进行排序

[英]C# Sorting a list of strings that contains numbers

I am creating a score system which reads/writes to a text file. 我正在创建一个读/写文本文件的分数系统。 My current format reads each line of the file and stores each line into a List<string> . 我当前的格式读取文件的每一行,并将每行存储到List<string> A typical line would be something like 50:James (50 being the score, James being the username) . 典型的一行就像是50:James (50 being the score, James being the username)

I need to order the list by the score while keeping the name with the string. 我需要按照分数对列表进行排序,同时保持名称与字符串。 Here's an example of what I mean: 这是我的意思的一个例子:

Unordered text file: 无序文本文件:

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

(Notice how there are some scores that are the same, hindering my use of creating a list using numerical keys) (请注意,有些分数是相同的,阻碍了我使用数字键创建列表的使用)

Ordered List: 订购清单:

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

My current code (That does NOT work with two or more of the same score) 我当前的代码(不能与两个或多个相同的分数一起使用)

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;

Yes, I know this is TERRIBLY inefficient and ugly, but I spent ages trying so many different methods. 是的,我知道这是非常低效和丑陋的,但我花了很多时间尝试这么多不同的方法。

You can use String.Split : 你可以使用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();

Edit : Here's a demo with your data on Ideone: http://ideone.com/gtRYO7 编辑 :这是一个关于Ideone数据的演示: http ://ideone.com/gtRYO7

You can use the ReadAllLines method to easily read the file, then OrderByDescending to sort the strings on values that you parse from them: 您可以使用ReadAllLines方法来轻松地阅读文件,然后OrderByDescending到您从中解析价值观的字符串进行排序:

string[] sortedScoreLines =
  File.ReadAllLines(resourcePath + "\\scoreboard.txt")
  .OrderByDescending(s => Int32.Parse(s.Substring(0, s.IndexOf(':'))))
  .ThenBy(s => s)
  .ToArray();

Based on Guffa's answer with some more comments 基于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();

Check this: 检查一下:

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();
    }

Lots of good answers already. 已经有很多好的答案了。 I just wanted to provide an even shorter version: 我只想提供更短的版本:

List<string> ordered = list.OrderByDescending(s => int.Parse(Regex.Match(s, @"\d+").Value)).ToList();

(of course, this assumes that there are no other numbers in your items besides the ones at the beginning) (当然,这假设除了开头的项目之外,您的项目中没有其他数字)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM