Understanding Ternary Operators: Simplifying Ternary Conditional Logic over If/Else Statements
Introduction
My first encounter with conditional (ternary) operations was when I first ventured into the world of programming. Along my journey, I was tasked with writing a monty program, where I had to define a data structure to use in the program and I relied on my first ever conditional macro, instead of the traditional if … else
conditional logic. This is the last line of the code snippet below. This article will focus on Python
and JavaScript
ternary and conditional expressions. The C
code snippet is only an example.
#define USE_STACK 2
#define USE_QUEUE 1
#define USE_DEFAULT 0
/* macro definitions for stack, queue and dataStruct */
#define _stack(opcode) (strcmp((opcode), "stack") == 0)
#define _queue(opcode) (strcmp((opcode), "queue") == 0)
#define _dataStruct(opcode) ((_stack(opcode)) ? USE_STACK : ((_queue(opcode)) ? USE_QUEUE : USE_DEFAULT))
Explanation of conditional logic in programming
Conditional logic in programming is the use of statements or expressions to execute code based on whether certain conditions are true or false. This process or idea allows programs to make decisions, resulting in different actions, depending of varying inputs and or circumstances. Conditional logic is fundamental in programming, allowing for dynamic control flow based on varying conditions. We have all encountered this concept, so long as we make use of software, be it at the low level or as a user who has no idea of any programming concept. A basic use case of conditional logic is form validation. When attempting to log into a service, we are met with either passing valid or invalid input, the outcome of which is based on conditional logic. Example:
user = {
"username": "Azara",
"password": "userpwd",
}
def login(user: dict) -> str:
if user.get("username") and user.get("password"):
return "Success"
else:
return "Invalid Credentials"
Brief overview of if/else statements
if … else
statements, perhaps, the most basic and well-known statement type, is the most basic form of conditional logic. Based on the example above, an if
statement checks a condition, and if true, executes a block of code. The else
statement runs if the condition is false.
age = 18
if age >= 18:
print("Adult")
else:
print("Minor")
In the snippet above, the final outcome will be “Adult” because the if
statement is a true statement after evaluating the condition age >= 18
.
Introduction to ternary operators
What is a Ternary Operator?
Ternary operators are shorthand methods or ways of handling conditional logic in programming. They are frequently used as one-liner alternatives to if … else
statements. There, however, are instances where ternary operations span multiple lines. These instances are often noticed in conditional chaining, just as instances where if … else
statements are chained using elif
as used in python or else if
as used in JavaScript. Though conditional chaining of ternary operations span multiple lines, there are much more fewer lines as compared to traditional if … elif … else
statements.
Basic syntax
# syntax: x if a > b else y
person = {
"name": "Azara",
"city": "Accra",
"country": "GH",
}
def greeting(person: Dict) -> str:
name = person.get("name") if person else "stranger"
city = person.get("city") if person else "unknown"
country = person.get("country") if person else "unknown"
greeting_card = f'Hello there, {name}, from the city of {city}!'
return greeting_card
print(greeting(person))
# Hello there, Azara, from the city of Accra!
The expression x if a > b else y
first evaluates the condition, a > b rather than x. If a > b is true, x is evaluated and its value is returned; otherwise, y is evaluated and its value is returned.
Similarly, the expression person.get("name") if person else “stranger”
first evaluates the condition, person
rather than person.get("name")
. If the condition checks, person.get("name")
is then evaluated and its value returned; otherwise, “stranger”
is returned.
In JavaScript, the syntax is condition ? expressionIfTrue: expressionIfFalse
.
Condition: The test or logic to evaluate. eg.
a > b
expressionIfTrue: Result if condition is
true
.expressionIfFalse: Result if condition is
false
.
// syntax: condition ? exprIfTrue : exprIfFalse
const person = {
name: "Azara",
city: "Accra",
country: "GH",
};
const greeting = (person) => {
const name = person ? person.name : "stranger";
const city = person ? person.city : "unknown";
const country = person ? person.country : "unknown";
const greetingCard = `Hello there, ${name}, from the city of ${city}!`;
return greetingCard;
};
console.log(greeting(person));
// Hello there, Azara, from the city of Accra!
Just like the explanation given for python, the expression condition ? exprIfTrue : exprIfFalse
first evaluates the condition. If the condition is true, exprIfTrue
is returned; otherwise, exprIfFalse
is returned.
Comparison with if/else statements
In python, the one-liner conditional expression person.get("name") if person else "stranger"
would have been written using if/else as:
if person:
name = person.get("name")
else:
name = "stranger"
And in JavaScript, the one-liner ternary operator person ? person.name : "stranger";
would have been written using if/else as:
if person {
const name = person.name;
} else {
const name = "stranger";
}
Notice how in all one-liners we had to declare the name variable to store the person’s name only once, but in the if … else
statements, we had to declare the same name variable twice?
Common languages that support ternary operators
We have already seen my example ternary operator which was written in C and subsequent examples that I have elaborated on written in Python and JavaScript. There are other programming languages such as C++, PHP, Java and more that also support ternary operators.
Benefits of Using Ternary Operators
Conciseness and readability
We can attest, based on the examples above, that ternary operators indeed help with code conciseness and code readability. They help reduce code length and squeeze code logic to very fewer lines, making it easy to read when conditions are simple. This is particularly beneficial in short functions or expressions where brevity improves clarity. Instead of writing about 5 lines to check a condition, you can write:
const age = process.argv[1]
const userStatus = (age >= 18) ? "Adult" : "Minor";
or in Python:
age = sys.argv[1]
user_status = "Adult" if age >= 18 else "Minor"
Simplification of simple conditional assignments
Just like in the examples under Comparison with if/else statements, for cases where a variable assignment depends on a condition, ternary operators are perfect for simplifying code. Without the need for an extra code block, you can keep the variable assignment brief and focused.
Enhancing code clarity in certain cases
In instances where conditional logic is easy to understand, using ternary operators add a bit more clarity, helping reduce visual clutter.
When to Use Ternary Operators
Appropriate situations for employing ternary operators
Ternary operators are best used when:
The logic is basic and or simple, like assigning a value based on a condition.
The condition is a straightforward check that does not require nesting.
The use of a ternary operator improves readability without necessarily sacrificing clarity (more on this below).
Examples of effective use cases
<Link to='/cart' className='bg-primary p-1 sm:px-6 px-2 flex items-center rounded-md space-x-2 font-primary'>
<HiMiniShoppingBag />
{
cartItems.length > 0 ? <span className='text-sm font-semibold'>{ cartItems.length }</span> : <span className='text-sm font-semibold'>0</span>
}
</Link>
I have had to continuously fallback on ternary operators in a bookstore react frontend application I am writing to dynamically display the number of items in a user’s cart. As can be seen in the code snippet above, cartItems.length > 0
is the condition and if the condition is true
, we return the cartItems.length
value; otherwise, we return a default value, 0.
Removing the span element and the tailwindcss class names, we have a conditional logic being represented by a ternary operator in JavaScript as { cartItems.length > 0 ? cartItems.length : 0 }
which if represented in an if/else statement, would look like:
// ternary one-liner
{ cartItems.length > 0 ? cartItems.length : 0 }
// if/else statement
if (cartItems.length > 0) {
return cartItems.length;
} else {
return 0;
}
Scenarios where ternary operators should be avoided
Avoid ternary operators when:
The condition is complex and involves multiple layers.
Nesting multiple ternary operators, as this quickly becomes hard to read and maintain.
There’s a need for more than two potential outcomes (use
if/else if
orswitch
instead).
Example:
const getGrade = (score) => {
if (score === 100) {
return "A++";
} else if (score >= 90) {
return "A";
} else if (score >= 80) {
return "B";
} else if (score >= 70) {
return "C";
} else if (score >= 60) {
return "D";
} else {
return "F";
}
};
Nesting the example snippet above, we risk falling into a conditional chaining process;
Conditional chaining refers to the practice of linking multiple conditional statements together, allowing for more complex decision-making processes.
const getGrade = (score) => {
return (score === 100) ? "A++"
: (score >= 90) ? "A"
: (score >= 80) ? "B"
: (score >= 70) ? "C"
: (score >= 60) ? "D"
: "F"
};
We may have managed to reduce the code length from 15 to 7 lines and it looks easy on the eye. But some may have trouble reading the latter example as opposed to the traditional if/else example, especially when we attempt to condense this into a single line. It is a matter of choice, really.
const getGrade = (score) => {
return (score === 100) ? "A++" : (score >= 90) ? "A" : (score >= 80) ? "B" : (score >= 70) ? "C" : (score >= 60) ? "D" : "F"
};
With the above one-liner example, we can agree that due to the brevity of ternary operators, developers may be tempted to condense overly complicated logic into a single line, reduce code clarity for the next developer who may be required to have access to the same code for dev purposes.
Example of a more complex scenario:
Let us consider an instance where multiple conditions need to be evaluated to determine a user’s access level.
def get_user_access_level(user: dict) -> str:
if user.get("role") == "admin" and user.get("verified"):
return "Full Access"
elif user.get("role") == "editor" and user.get("verified"):
return "Editor Access"
elif user.get("role") == "viewer":
return "View Only"
else:
return "No Access"
In the above case, using a nested if/else statement provides a clearer logic than relying on a complex ternary operation like in the JavaScript example below:
const getUserAccessLevel = (user) => {
return user.role === "admin" && user.verified ? "Full Access"
: user.role === "editor" && user.verified ? "Editor Access"
: user.role === "viewer" ? "View Only"
: "No Access";
};
Conclusion
Ternary operators offers a developer a concise and readable approach to handling simple conditional logic in programming. They are particularly useful for straightforward conditions and variable assignments, reducing code length and enhancing visual clarity when used appropriately. However, avoid ternary operators in complex scenarios where readability might be compromised.
So, a developer should always aim for a balance, using ternary operators where they enhance code clarity and avoiding them when faced with a more complex conditional logic. We can write cleaner and more efficient code when we master the usage of ternary operators, ultimately improving the overall quality of our programming projects.
References:
conditional (ternary) operator - mdn web docs_
expressions - python docs
PEP 308 - conditional expressions
Subscribe to my newsletter
Read articles from Yushahu Yussif Azara directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by