When to use ternary condition?

Asked

Viewed 3,950 times

15

I particularly like the use of ternary condition, but I see many developers saying no, there is even a rule in Checkstyle when validating your code that encourages you not to use.

See the example below:

var idElemento = $(this).attr("id");
var isDataInicial = idElemento.contains("Inicial");
$("#" + (isDataInicial ? idElemento.replace("Inicial", "Final") : idElemento.replace("Final", "Inicial"))).datepicker("option", isDataInicial ? "minDate" : "maxDate", selectedDate == "" ? null : selectedDate);

Apart from the fact that if something else has to be implemented when the condition is true and/or false we will have more work to undo the ternary and create the structure if/else I don’t see any problem in the above code, maybe a better formatting at most, but in a row was solved the problem that without the ternary we would have something like:

if ((idElemento.contains("Inicial")) {
    if (selectedDate == "") {
        $("#" + idElemento.replace("Inicial", "Final")).datepicker("option", "minDate", null);
    } else {
        $("#" + idElemento.replace("Inicial", "Final")).datepicker("option", "minDate", selectedDate)
    }
} else {
    if (selectedDate == "") {
        $("#" + idElemento.replace("Final", "Inicial")).datepicker("option", "maxDate", null);
    } else {
        $("#" + idElemento.replace("Final", "Inicial")).datepicker("option", "maxDate", selectedDate)
    }
}

So the question remains, when should we use the ternary? And it is so bad to use ternaries nested with a good identation?

4 answers

13


Your chain of if proposal is not the only way to represent the same code:

var idElemento = $(this).attr("id");
var isDataInicial = idElemento.contains("Inicial");

var idEscolhido, opcaoDP, data;
if ( isDataInicial ) {
    idEscolhido = idElemento.replace("Inicial", "Final");
    opcaoDP = "minDate";
}
else {
    idEscolhido = idElemento.replace("Final", "Inicial");
    opcaoDP = "maxDate";
}
if ( selectedDate == "" )
    data = null;
else
    data = selectedDate;

$("#" + idEscolhido).datepicker("option", opcaoDP, data);

The above code is longer, but more readable than both alternatives. Only in the case of data, is that something would be gained by using the ternary operator:

var data = (selectedDate == "" ? null : selectedDate);

(optional parentheses, but I always put when I use the ternary operator in a single row, for emphasis)

That said, I have nothing against using the ternary operator whenever it brings clarity and concision to your code. Even in the case of multiple conditions, it can be put in a well formatted, easy to read:

int result = FirstCheck() ? 1 : 
             SecondCheck() ? 2 : 
             ThirdCheck() ? 3 : 
             0;

What makes your original example problematic is that you used 3 times the ternary operator in a single line. This not only makes it difficult to read, but also difficult to debug (i.e. if you need to put a breakpoint and/or a console.log to inspect the behavior of your program, it is impossible to do so in this format).

  • 3

    I agree with you that debugging in JS would be an almost impossible task unless you isolate on consoles.log each of the ternary ifs, now with the current Java Ides you don’t even need to use sysout (equivalent to a console.log) for this. But I liked the use of parentheses to emphasize the ternary.

11

I recommend using it only when the resulting instruction is extremely short and represents a significant increase in concision over the equivalent if/Else without sacrificing readability.

Good example:

int result = Check() ? 1 : 0;

Bad example:

int result = FirstCheck() ? 1 : SecondCheck() ? 1 : ThirdCheck() ? 1 : 0;

Before using the ternary operator, you should consider the complexity of the situation at hand. Avoid nesting or stacking your operations, even if you are comfortable with them, as this can lead to very confusing code and unintuitive results. It’s still better to use IF statements for complex situations. Above all, have a nice code for the next guy who will fiddle and try to keep your code clean and easy to understand.

  • I think it’s a bit of a matter of taste, this bad example you gave and I also saw many agreeing there in the OS I find simply much easier to read. In a look I understood that they are three conditions and which exits from each one. I even agree that nested suits can lead to some confusion, but if you look at my example I didn’t use them nested, but I used three different suits in one line.

  • Like you said it’s a matter of taste, and if you work in a group you can talk to the work staff and see what they think is best...

  • Here they use the Checkstyle I mentioned at the beginning.

11

Robert Cecil Martin, author of the book Clean Code, suggests in the first chapter the following metric for the quality of a source code: the amount of times you hear your colleagues say "WTF" while reviewing your code (seriously!).

Already for the computer, whatever. As you have explained in a certain way in the question, in general the form:

a ? b : c;

Is equivalent to:

if (a) { b; } else { c; }

Since the machine is indifferent, what defines the "best" and the "worst" form for each case is readability and ease of maintenance. This varies from situation to situation. It is possible that both changes as the "best" form at different points of the same code file. If you program as a team, talk to your colleagues to reach a consensus and standard. If you program alone, reread codes you have written in the past, and see the form that is easiest for you to understand.

Going back over the question, I can think of two situations where one way is better than the other.

When we have many conditions we want to test, one if may be more readable.

if ((a == null &&
        b != null &&
        c ^ d) ||
        (e && !f) ||
        g)
{
    foo();
}
else
{
    bar();
}

If written in the ternary way, it would be:

((a == null && b != null && c ^ d) || (e && !f) || g) ? foo() : bar;

You can keep adding conditions until the expression is larger than the screen. Breaking in lines can get weird in ternary form.

Note that this was a hypothetical case and illustrative. It is much better to create a Boolean variable calculated as a result of all conditions, when there are many, and then use this variable in the if or in the term ternary.

On-line code is where the term ternary proves particularly useful. For example:

int a = foo(b ? c : d);

It’s more compact than:

int a;
if (b)
{
    a = foo(c);
}
else
{
    a = foo(d);
}

Although this looks like the previous comparison, note the subtle difference: you cannot use a block if within the call of a method or function (at least in most languages of the C family - I cannot make a strong statement for all languages).

  • 2

    Very nice your answer also addressing a new aspect. I also do not use suits with too long conditions, in fact even with IF I use too big conditions, I always try to isolate in variables so the code is more readable as you suggested yourself.

1

I had doubts about the use of the ternary and, considering the great ease that the ternary can bring, besides today have improved the visualization (this stack is about Javascript, but PHP brings in some new paradigms), the following structure:

var valor = (acao == 1)
    ? primeiroValor
    : ((acao == 2)
        ? segundoValor
        : terceiroValor);

With these standards, as I mentioned PHP, there are PSR, who seek to standardize the code and, seeing that a unit exists among the community, decrease the calls "Questions of taste"

Browser other questions tagged

You are not signed in. Login or sign up in order to post.