Reputation: 81
I have a list, each element in the list is a string that contains date and integer in specific format: yyyyMMdd_number.
List<string> listStr = new List<string> { "20170822_10", "20170821_1", "20170823_4", "20170821_10", "20170822_11", "20170822_5",
"20170822_2", "20170821_3", "20170823_6", "20170823_21", "20170823_20", "20170823_2"};
When use method listStr.Sort();
Result as below:
20170821_1 20170821_10 20170821_3 20170822_10 20170822_11 20170822_2 20170822_5 20170823_2 20170823_20 20170823_21 20170823_4 20170823_6
Expected Output:
20170821_1 20170821_3 20170821_10 20170822_2 20170822_5 20170822_10 20170822_11 20170823_2 20170823_4 20170823_6 20170823_20 20170823_21
The way: i think every string(day_number) will split with an underline, then compare and sort by number. But please suggest me LINQ solution or better way to sort in this case.
Upvotes: 1
Views: 4816
Reputation: 1048
The answers above are much easier to follow / understand, but purely as an alternative for academic interest, you could do the following:
var sorted = listStr.OrderBy(x => Convert.ToInt32(x.Split('_')[0])*100 + Convert.ToInt32(x.Split('_')[1]));
It works on the premise that the suffix part after the underscore is going to be less than 100, and turns the two elements of the string into an integer with the relative 'magnitude' preserved, that can then be sorted.
The other two methods are much, much easier to follow, but one thing going for my alternative is that it only needs to sort once, so would be a bit faster (although I doubt it is going to matter for any real-world scenario).
Upvotes: 1
Reputation: 219047
I imagine any numeric ordering would first require converting the value to a numeric type. So you could split on the underscore, sort by the first value, then by the second value. Something like this:
list.OrderBy(x => x.Split('_')[0]).ThenBy(x => int.Parse(x.Split('_')[1]))
You could improve this, if necessary, by creating a class which takes the string representation on its constructor and provides the numeric representations (and the original string representation) as properties. Then .Select()
into a list of that class and sort. That class could internally do type checking, range checking, etc.
Upvotes: 2
Reputation: 726987
Since the dates are in the format that can be ordered lexicographically, you could sort by the date prefix using string ordering, and resolve ties by parsing the integer:
var sorted = listStr
.OrderBy(s => s.Split('_')[0])
.ThenBy(s => int.Parse(s.Split('_')[1]));
Upvotes: 10