Is it possible to evaluate a ternary expression with 3 possible values?

1

Let's say I have this account:

var total = valor1 / valor2;

The result could be three possible values, type:

  • total > 5
  • total > 0 and total < 5
  • a positive value

Note: These are percentage values, so 5% equals 0.05.

I could use a if to test everything, but the question is: similar to a ternary operator, is it possible?

    
asked by anonymous 30.01.2018 / 16:26

2 answers

8

No. The ternary operator only works with two expressions.

The most you can do is something like the code below, nesting the ternaries.

Keep in mind that this makes the code extremely difficult to read.

var resultado = total < 5 ? 
                  ((total > 0) ? "Menor que cinco, mas maior que zero" 
                               : "Menor que cinco, zero ou menos") 
                : "Maior ou igual a cinco";

See working on .NET Fiddle

Editing

How do I know that you are an admirer of expressions, lambdas, functions, and so on. And I also remember a question that you deleted where I asked something like avoiding a lot of if's using expressions, I decided to write a code with that adapted to the current problem.

Keep in mind that this is not a concrete solution given the circumstances, you can rather take advantage of this code, but I believe not for the current problem.

Explanation: The code is basically based on a list of key-value pairs, where each element of this list is keyed to an expression that takes as input (parameter) a decimal number and returns a boolean ( Func<decimal, bool> ). The values of these pairs are a descriptive string with the result, obviously this can be changed to anything, but I decided to leave it thus to become more illustrative.

The ValidarTotal method iterates over all these items, calls the function (which is the key of the pair) by passing the valor parameter to the function, and if the result is true , returns the value of the pair. Obviously it is possible to change for this to be grouped, I did this in the ValidarTotalAgrupado method. The idea of it is the same as the first one, with the difference that it will return a string with all values where the function returned true and that I used LINQ.

Code:

KeyValuePair<Func<decimal, bool>, string>[] pares = new[]   
{
    new KeyValuePair<Func<decimal, bool>, string>(valor => valor > 5, "Maior que 5"),
    new KeyValuePair<Func<decimal, bool>, string>(valor => valor > 0 && valor < 5, "Maior que 0 e menor que 5"),
    new KeyValuePair<Func<decimal, bool>, string>(valor => valor > 0, "Número positivo")
};

static string ValidarTotalAgrupado(decimal valor, params KeyValuePair<Func<decimal, bool>, string>[] pares)
{
    var ret = pares.Where(p => p.Key(valor))
                   .Select(p => p.Value)
                   .Aggregate((a, b) => $"{a}, {b}");

    return ret;
}

static string ValidarTotal(decimal valor, params KeyValuePair<Func<decimal, bool>, string>[] pares)
{
    foreach(var item in pares)
    {
        if(item.Key(valor)) {
            return item.Value;
        }
    }   
    return null;
}

void Main()
{   
    var testes = new[] 
    {
        new { Valor = 6m },
        new { Valor = 2m },
        new { Valor = 0.5m }
    };

    foreach(var teste in testes)
    {
        var res = ValidarTotal(teste.Valor, pares);
        var resAgrupado = ValidarTotalAgrupado(teste.Valor, pares);

        Console.WriteLine($"Valor: {teste.Valor:n2}\nResultado: {res}\nAgrupado: {resAgrupado}\n");
    }
}

See working in .NET Fiddle.

    
30.01.2018 / 16:37
9

You can use nested conditional operators, but you are discouraged by decreasing readability, although you can help a little:

resultado = total > 5 ? 5 :
            total < 5 ? 1 :
            total > 0 ? 0;
    
30.01.2018 / 16:32