简体   繁体   English

按从高到低的数字对列表(字符串)进行数字排序

[英]Sorting a list (string) numerically from high to low c#

Context: I am designing a leader board and want to have the data displayed from the highest score to the lowest score. 上下文:我正在设计排行榜,并且希望显示从最高分到最低分的数据。 The problem being the data contains a string and integers which are imported from a text file. 问题在于数据包含从文本文件导入的字符串和整数。 Currently I am able to sort the data numerically however I am using the OrderByDescending function which does not work. 目前,我可以对数据进行数字排序,但是我正在使用不起作用的OrderByDescending函数。 Eg 11,4,5,8,23,65 when ordered = 8,65,5,4,23,11 (sorted alphanumerically). 例如,订购时= 11,4,5,8,23,65 = 8,65,5,4,23,11(按字母数字排序)。 The list contains the data: name(string), difficulty(string) and score(int) and I wish to sort the data in a descending order: Eg 1st = 10, 2nd = 9 etc. 该列表包含数据:名称(字符串),难度(字符串)和得分(整数),我希望以降序对数据进行排序:例如1st = 10、2nd = 9等。

List<string> leaderboardList = new List<string>();
StreamReader srUserData = new StreamReader(@"User Leaderboard.txt");
while ((userDataLine = srUserData.ReadLine()) != null)
        {
            leaderboardList.Add(userDataLine);
        }

leaderboardList = leaderboardList.OrderByDescending(x => Regex.Match(x, @"\d+").Value).ToList();

The Regex.Match finds the number in the string. Regex.Match在字符串中找到数字。 Basically the final line is the line that needs amending. 基本上,最后一行是需要修改的行。 All help welcome, thanks. 欢迎所有帮助,谢谢。

Edit: The data should be outputted in the form Name, difficulty, score and sort the data in a descending order with the highest score. 编辑:数据应以名称,难度,分数和最高分数的降序排列。

Just change: 只是改变:

leaderboardList = leaderboardList.OrderByDescending(x =>
    Regex.Match(x, @"\d+").Value).ToList();

To: 至:

leaderboardList = leaderboardList.OrderByDescending(x =>
    Int32.Parse(Regex.Match(x, @"\d+").Value)).ToList();

Just add the Int32.Parse really. 只需添加Int32.Parse即可 A caveat though: If you pass a string that is not a number Int32.Parse() will throw an exception. 需要注意的是:如果传递的字符串不是数字,则Int32.Parse()将引发异常。 If this is a possibility that needs to be handled, then you can use Int32.TryParse instead. 如果有可能需要处理,则可以改用Int32.TryParse

Ex: 例如:

int testValue = 0; //This is only used for TryParse()
leaderboardList = leaderboardList.OrderByDescending(x =>
        Int32.TryParse(Regex.Match(x, @"\d+").Value, out testValue)
        ? testValue : 0M).ToList();

Tested using the following example list: 使用以下示例列表进行了测试:

List<string> leaderboardList = new List<string>();
leaderboardList.Add("Brandon|Easy|9");
leaderboardList.Add("Yoda|Impossible|9001");
leaderboardList.Add("Barney|Easy|-1");
leaderboardList.Add("John|Normal|500");

This code works correctly, and the TryParse code was not needed. 此代码可以正常工作,并且不需要TryParse代码。

Output: 输出:

Yoda|Impossible|9001
John|Normal|500
Brandon|Easy|9
Barney|Easy|-1

I suggest a completely different approach from the others. 我建议与其他方法完全不同的方法。 Load your string from disk, then parse it into a class you have defined. 从磁盘加载字符串,然后将其解析为您定义的类。 For example: 例如:

public class LeaderboardRow
{
    public string Name { get; set; }
    public string Difficulty { get; set; }
    public int Score { get; set; }
}

Then your code would look more like this: 然后您的代码将更像这样:

List<LeaderboardRow> leaderboardList = new List<LeaderboardRow>();
StreamReader srUserData = new StreamReader(@"User Leaderboard.txt");
while ((userDataLine = srUserData.ReadLine()) != null)
{
    //Put logic here that parses your string row into 3 distinct values
    leaderboardList.Add(new LeaderboardRow()
    {
        Score = 0, //put real value here
        Name = string.Empty, //put real value here
        Difficulty = string.Empty //put real value here
    });
}

Then any ordering you need to do is a simple LINQ statement: 然后,您需要执行的任何排序都是一个简单的LINQ语句:

leaderboardList = leaderboardList.OrderByDescending(x => x.Score).ToList();

Depending on your scenario/requirements you could store this text as json instead which could speed up and simplify your application. 根据您的方案/要求,您可以将此文本存储为json,这可以加快并简化您的应用程序。

You could go old school and perform Integer.TryParse or some derivative of such functions. 您可以去老学校并执行Integer.TryParse或此类函数的某些派生类。 Once you do that you can append them into a list of integers. 完成后,您可以将它们附加到整数列表中。

int number;
bool result = Int32.TryParse(value, out number);
if (result) {
Console.WriteLine("Converted '{0}' to {1}.", value, number);
}

You missed one thing, that is you are not convert Regex value to int. 您错过了一件事,那就是您没有将Regex值转换为int。 Please check below code, it's works for me. 请检查以下代码,它对我有用。

CODE: 码:

List<string> leaderboardList = new List<string>();
leaderboardList.Add("A,A,9");
leaderboardList.Add("B,B,8");
leaderboardList.Add("G,C,65");
leaderboardList.Add("S,B,10");

leaderboardList = leaderboardList.OrderByDescending(x =>Convert.ToInt32((string.IsNullOrEmpty(Regex.Match(x, @"\d+").Value)?"0":Regex.Match(x, @"\d+").Value))).ToList();
foreach (var item in leaderboardList)
{
    Console.WriteLine(item);
}

Online output: .Net Fiddle Output 在线输出: .Net小提琴输出

You can use this for ordering list of numbers in string or list of string that contains numbers. 您可以使用此命令对字符串中的数字列表或包含数字的字符串列表进行排序。

The Alphanum Algorithm Alphanum算法

I hope this works for you. 希望这对您有用。

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

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