Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

LINQ order by alphabetical followed by empty string

Tags:

c#

linq

I have a collection of strings:

"", "c", "a", "b".

I want to use LINQs orderby so that the order is alphabetical but with empty strings last. So in the above example the order would be:

"a", "b", "c", ""
like image 828
robasaurus Avatar asked Sep 13 '13 12:09

robasaurus


2 Answers

You could use something like:

var result = new[] { "a", "c", "", "b", "d", }
    .OrderBy(string.IsNullOrWhiteSpace)
    .ThenBy(s => s);

 //Outputs "a", "b", "c", "d", ""
like image 64
Oliver Avatar answered Nov 13 '22 00:11

Oliver


Alternatively to the existing answers, you could provide an IComparer<string> to the OrderBy overload:

class Program
{
    static void Main(string[] args)
    {
        var letters = new[] {"b", "a", "", "c", null, null, ""};

        var ordered = letters.OrderBy(l => l, new NullOrEmptyStringReducer());

        // Results: "a", "b", "c", "", "", null, null

        Console.Read();
    }
}

class NullOrEmptyStringReducer : IComparer<string>
{
    public int Compare(string x, string y)
    {
        var xNull = x == null;
        var yNull = y == null;

        if (xNull && yNull)
            return 0;

        if (xNull)
            return 1;

        if (yNull)
            return -1;

        var xEmpty = x == "";
        var yEmpty = y == "";

        if (xEmpty && yEmpty)
            return 0;

        if (xEmpty)
            return 1;

        if (yEmpty)
            return -1;

        return string.Compare(x, y);
    }
}

I don't state that this is a good example of the IComparer implementation (it probably needs to do null checking and handle if both strings are empty), but the point of the answer is to demonstrate the OrderBy overload and at the very least works with the question's sample data.

Due to feedback in the comments and my own curiosity, I've provided a slightly more involved implementation that also takes care of ordering empty strings and null strings relative to each other. Whitespace is not handled.

Still, the point is the ability to provide IComparer<string>, not how well you choose to write it :-)

like image 21
Adam Houldsworth Avatar answered Nov 13 '22 00:11

Adam Houldsworth