2013-02-24 96 views
3

我正在创建一个读取/写入文本文件的分数系统。我目前的格式读取文件的每一行,并将每行存储到List<string>。一条典型的线路就像50:James (50 being the score, James being the username)C#排序包含数字的字符串列表

我需要按分数排序列表,同时保持字符串的名称。下面是我的意思的例子:

无序文本文件:

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; 

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

回答

9

您可以使用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

+0

+1,打我吧:) – Bort 2013-02-24 20:04:24

+1

考虑增加所发生的事情的解释。我非常怀疑OP了解这些代码。 – evanmcdonnal 2013-02-24 20:06:21

+0

它完美无缺地工作,非常感谢!诚然,我不明白,但我会做一些研究! – 2013-02-24 20:11:40

3

可以使用ReadAllLines方法来轻松地阅读文件,然后OrderByDescending排序在你解析的值上的字符串:

string[] sortedScoreLines = 
    File.ReadAllLines(resourcePath + "\\scoreboard.txt") 
    .OrderByDescending(s => Int32.Parse(s.Substring(0, s.IndexOf(':')))) 
    .ThenBy(s => s) 
    .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(); 
    } 
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();