SilverLight
SilverLight

Reputation: 20468

How Sort A List<string> By A Part Of That String Desc

i have a list like this :

List<string> list_lines = new List<string>();
list_lines.add("name1__pass1__com__14__55");
list_lines.add("name2__pass2__com__14__5445");
list_lines.add("name3__pass3__com__14__456456");
list_lines.add("name4__pass4__com__14__1357");
list_lines.add("name5__pass5__com__14__20000");
list_lines.add("name6__pass6__com__14__25");
list_lines.add("name7__pass7__com__14__12");

and more...

as you see there is a separator here -> "__" in every string in that list.
mean :

string[] Separator = new string[] { "__" };   

foreach(string s in list_lines)
{
    string[] line_ar = s.Split(Separator, StringSplitOptions.None);
    int Num  = int.parse(line_ar[4]);
}

i want to sort that list by Num parts of that list.
i test some methods using StackOverflow, but there was a bug in them for a big list.

would be really appreciate to help me for soting it

Upvotes: 2

Views: 5855

Answers (6)

Wolfgang Jacques
Wolfgang Jacques

Reputation: 769

Forgive me for answering a related question here:

Sat 2020-03-21 06:03:31.129: 03: [100001] Player 1
Sat 2020-03-21 06:03:33.119: 02: [620524] Player 22

I would like to first sort the list by: 1) The number within the two [] 2) The date up until the : nn:

Here's one way (of many ways) to do it:

void Main()
{
    var originalList = new List<string>
    {
        @"Sat 2020-03-21 06:03:31.129: 03: [100001] Player 1",
        @"Sat 2020-03-21 06:03:33.119: 02: [620524] Player 22",
    };
    var sortableList = originalList.Select(x => splitTheLine(x));
    var result = sortableList.OrderBy(x => x.numberPart).ThenBy(x => x.datePart).Select(x => x.wholeString);
}

(DateTime datePart, int numberPart, string wholeString) splitTheLine(string x)
{
    string[] separator = { "[", "]", ": " };
    var result = x.Split(separator, StringSplitOptions.None);
    return (DateTime.Parse(result[0]), int.Parse(result[3]), x );
}

I define a method splitTheLine to extract the date and number parts along with the original string. It returns a tuple. Then I use the method with the select operator of LINQ to retrieve a list with three "columns". Again with LINQ, using the OrderByand ThenByoperators I sort the list. Finally I selectonly the originial string for the result.

This solution can be shortened a lot - but at the cost of readability, as usual.

Upvotes: 0

Jeppe Stig Nielsen
Jeppe Stig Nielsen

Reputation: 61952

The other answers create a new list which is sorted the way you want. If instead you want the same list to be sorted, maybe try something like this:

Func<string, int> getNum = str => int.Parse(str.Split(Separator, StringSplitOptions.None)[4]);
list_lines.Sort((x, y) => getNum(x).CompareTo(getNum(y)));

This uses an overload of List<>.Sort. If you want descending order, swap x and y in the Comparison<> lambda body.

If your list is very long, this is faster (uses Quick Sort) and doesn't require the memory of a new copy of the list.

Upvotes: 1

Diego
Diego

Reputation: 16714

Asc:

list_lines = list_lines.OrderBy(s => int.Parse(s.Split(Separator, StringSplitOptions.None)[4])).ToList();

Desc:

list_lines = list_lines.OrderByDescending(s => int.Parse(s.Split(Separator, StringSplitOptions.None)[4])).ToList();

Upvotes: 10

Honza Brestan
Honza Brestan

Reputation: 10947

You can take advantage of lambda expression in LINQ functions like OrderBy

string[] Separator = new string[] { "__" };
var sortedList = list_lines
    .OrderBy(s => int.Parse(s.Split(Separator, StringSplitOptions.None)[4]))
    .ToList();

As an unrelated side note, please use correct C# naming conventions so your code is easier to read and is unified with existing C# code-base. E.g. not beginning local variable names with capital letter (Separator -> separator) and using lower camel case (Pascal case) in case it contains more words (list_lines -> listLines)

Upvotes: 0

Levi Botelho
Levi Botelho

Reputation: 25214

var myList = list_lines.OrderBy(x => int.Parse(x.Split(new string[] {"__"}, StringSplitOptions.None)[4])).ToList();

Upvotes: 3

M4N
M4N

Reputation: 96561

If the number always starts after the last underscore character, then this should work:

var sortedList = list_lines
    .OrderByDescending(l => int.Parse(l.Substring(l.LastIndexOf("_") + 1)))
    .ToList();

Upvotes: 2

Related Questions