Goid
Goid

Reputation: 33

How can I sort variable number of columns with Linq C#?

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

Answers (1)

Theodor Zoulias
Theodor Zoulias

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

Related Questions