Reputation: 33
The below code works for sorting two columns (by surname then first name), however I need to sort by a variable number of names (2-5 per entry). Adding another ThenBy split at whitespace causes an out of bounds exception. I understand why, but I was wondering if there is any way around this to get the code to work with Linq or if I need to go some other route. Apologies if this is simple, I'm completely new to C#. I have searched for an answer for a while and cannot find it.
The code below outputs to console:
Jimbo Crab
Jonathan Crab
Michael Crab
Steve Cruthers
Barry John
David Johnson
Correctly ordered first by surname then by given name.
However the names I need to sort are of varying lengths, i.e:
Barry John
Daniel Johnson James
Steve Davidson Andrew Colins
Lorna Michael
Which should produce:
Steve Davidson Andrew Colins
Daniel Johnson James
Barry John
Lorna Michael
These need to be sorted in reverse order, so by surname, then given names and finally forename.
Thanks in advance!
var listStr = new[] {
"Barry John", "Steve Cruthers", "Michael Crab", "David Johnson", "Jonathan Crab", "Jimbo Crab"};
var sorted = listStr
.OrderBy(s => s.Split(' ')[1])
.ThenBy(s => s.Split(' ')[0]);
foreach (var s in sorted)
{
Console.WriteLine(s);
}
}
Upvotes: 2
Views: 169
Reputation: 43525
It is easier and more efficient to split each string once, and then sort using the arrays. Finally you may join the arrays back to strings if you want.
var sorted = listStr
.Select(s => s.Split(' ')) // project string to an array
.OrderBy(a => a[a.Length - 1]) // order by last element
.ThenBy(a => a.Length > 2 ? a[1] : a[0]) // then order by middle element
.ThenBy(a => a[0]) // then order by first element
.Select(a => String.Join(" ", a)); // project back to a string
Upvotes: 2