Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I order an IEnumerable<T> such that a special item is always at the bottom? [duplicate]

Tags:

c#

I have an IEnumerable<string> being passed to me which has the following items:

  • HP
  • Canon
  • Lexmark
  • Samsung
  • Other

Now what I am trying to achieve is order the items alphabetically but I want to keep the other item last. I have gone ahead and used OrderBy(i => i)

which lists the items as follows:

  • Canon
  • HP
  • Lexmark
  • Other
  • Samsung

The desired result I want is

  • Canon
  • HP
  • Lexmark
  • Samsung
  • Other

I have tried using .OrderBy(i => i != "Other").ThenBy(i => i) but this puts Other item right at the top.

Can someone tell me how to achieve this please.

like image 569
Izzy Avatar asked Dec 10 '22 11:12

Izzy


2 Answers

You have to use OrderByDescending because true is "higher" than false

list.OrderByDescending(s => s != "Other")
    .ThenBy(s => s);

You could also use

list.OrderBy(s => s == "Other" ? 1 : 0)
    .ThenBy(s => s);

Since you have asked, here are extension methods which simplify it for future use:

public static IEnumerable<T> OrderFirst<T>(this IEnumerable<T> sequence, Func<T, bool> predicate)
{
    return sequence.OrderByDescending(predicate);
}

public static IEnumerable<T> OrderLast<T>(this IEnumerable<T> sequence, Func<T, bool> predicate)
{
    return sequence.OrderBy(predicate);
}

Example usage:

var list = new List<string> { "HP", "Other", "Samsung" };
var otherLast = list.OrderLast(s => s == "Other").ToList();
like image 91
Tim Schmelter Avatar answered Jan 18 '23 15:01

Tim Schmelter


I have tried using .OrderBy(i => i != "Other").ThenBy(i => i) but this puts Other item right at the top.

So you're almost there, you just need to reverse the sort order of your first criterion: Replace OrderBy by OrderByDesc or replace i != "Other" with i == "Other.

Of course, it does not hurt to be explicit: It's not obvious how Booleans are sorted, so I'd prefer:

.OrderBy(i != "Other" ? 1 : 2).ThenBy(i => i);
like image 25
Heinzi Avatar answered Jan 18 '23 15:01

Heinzi