Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ternary operator difficult to read

Any suggestion how to make the below query more "readable"?

var result = result
                .OrderBy(a =>
                    (conditionA) ?
                    valueA :
                    (conditionB ? valueB :
                    (conditionC ?
                    (conditionD ?
                    valueC : valueD) :
                    valueE)));

Its difficult to read with the long code of condition and value.

like image 383
YHTAN Avatar asked Jun 22 '16 08:06

YHTAN


1 Answers

There are several ways of improving the readability of your code.

Indentation

One way is to indent the code in a slightly different way, but this only helps readability a little:

var result = result.OrderBy(a =>
    conditionA ? valueA :
    conditionB ? valueB :
    conditionC ? conditionD ? valueC :
                              valueD :
                valueE);

if, else

You could also turn those ternary operators into a more readable chain of if, else.

var result = Result.OrderBy(a => {
    if (conditionA)
    {
        return valueA;
    }
    else if (conditionB)
    {
        return valueB;
    }
    else if (conditionC)
    {
        if (conditionD)
        {
            return valueC;
        }
        else
        {
            return valueD;
        }
    }
    else
    {
        return valueE;
    }
});

IComparer<>

One option would be to write your own implementation of IComparer<> and pass it to the OrderBy method. I don't know what type your object is or what type the keys are in your code, so I'm going to assume string keys.

public class MyClassComparer : IComparer<MyClass>
{
    public int Compare(MyClass x, MyClass y)
    {
        string xKey = getKey(x);
        string yKey = getKey(y);
        return string.Compare(xKey, yKey);
    }

    private string getKey(MyClass item)
    {
        if (item.conditionA)
        {
            return item.valueA;
        }
        else if (item.conditionB)
        {
            return item.valueB;
        }
        else if (item.conditionC)
        {
            if (item.conditionD)
            {
                return item.valueC;
            } 
            else
            {
                return item.valueD;
            }
        }
        else
        {
            return item.valueE;
        }
    }
}

Extension method

A final option would be to move your code to an extension method:

public static class MyClassExtensions
{
    public static string GetSortingKey(this MyClass item)
    {
        if (item.conditionA)
        {
            return item.valueA;
        }
        else if (item.conditionB)
        {
            return item.valueB;
        }
        else if (item.conditionC)
        {
            if (item.conditionD)
            {
                return item.valueC;
            } 
            else
            {
                return item.valueD;
            }
        }
        else
        {
            return item.valueE;
        }
    }
}

Using the last option, your call to OrderBy is simply:

result.OrderBy(a => a.GetSortingKey())
like image 92
Anders Marzi Tornblad Avatar answered Oct 17 '22 04:10

Anders Marzi Tornblad