Photo by dylan nolte on Unsplash
The Magic of Object Lookup
An if...else and switch statement alternative
Hot take: if...else and switch both suck*
* In certain circumstances
A solution to a problem of conditional outcomes I came across early on in my JavaScript learning journey is the object lookup method. It reduces messy or visually overwhelming code to something that I believe is far more elegant and readable. I have implemented it is a couple of the "Learn JavaScript" projects I have completed.
It has its limitations of course--at least limitations that I have come to believe exist--but in simple enough application, it is superior to alternatives, including ternary.
In a nutshell, switch
is just plain bloated and ugly and if...else
can quickly get out of hand if there are too many options, if there is nested if...else
, etc.
ryan-reynolds-but-why.gif
Take for example a function that returns the name of the day of a week, given a number from 1-7 inclusive.
The if...else solution
Longform if...else
is "readable", sure, and not "complex", but looking at it one might get the feeling that there are "too many lines of code to accomplish something relatively simple".
// Longform if...else
const getDayOfWeekLong = num => {
if (num === 1) {
return 'Sunday'
} else if (num === 2) {
return 'Monday'
} else if (num === 3) {
return 'Tuesday'
} else if (num === 4) {
return 'Wednesday'
} else if (num === 5) {
return 'Thursday'
} else if (num === 6) {
return 'Friday'
} else if (num === 7) {
return 'Saturday'
} else {
return 'https://www.youtube.com/watch?v=dQw4w9WgXcQ';
}
}
Even the ternary version--while somewhat more terse and readable--is something that when NOT formatted in the way seen immediately below, is wildly unreadable.
// Ternary if...else - formatted to be readable
const getDayOfWeekTernary = num => {
return (num === 1) ? 'Sunday'
: (num === 2) ? 'Monday'
: (num === 3) ? 'Tuesday'
: (num === 4) ? 'Wednesday'
: (num === 5) ? 'Thursday'
: (num === 6) ? 'Friday'
: (num === 7) ? 'Saturday'
: 'https://www.youtube.com/watch?v=dQw4w9WgXcQ';
}
Dear god ... why ...
// Ternary if...else - unformatted
const getDayOfWeekTernary = num => {
return (num === 1) ? 'Sunday' : (num === 2) ? 'Monday' : (num === 3) ? 'Tuesday' : (num === 4) ? 'Wednesday' : (num === 5) ? 'Thursday' : (num === 6) ? 'Friday' : (num === 7) ? 'Saturday' : 'https://www.youtube.com/watch?v=dQw4w9WgXcQ';
}
The switch solution
This one is especially annoying and ugly. It's easy enough to read along and understand what can/will happen--I'll concede there--but sheer the amount of lines is even more than if...else
.
Imagine if this had 20+ options!
const getDayOfWeekSwitch = num => {
let day;
switch(num) {
case 1:
day = 'Sunday';
break;
case 2:
day = 'Monday';
break;
case 3:
day = 'Tuesday';
break;
case 4:
day = 'Wednesday';
break;
case 5:
day = 'Thursday';
break;
case 6:
day = 'Friday';
break;
case 7:
day = 'Saturday';
break;
default:
day = 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'
}
return day;
}
Object lookup to the rescue
This can be further simplified by using return {...}[num] || ...
.
const getDayOfWeekLookup = num => {
let weekdays = {
1: 'Sunday',
2: 'Monday',
3: 'Tuesday',
4: 'Wednesday',
5: 'Thursday',
6: 'Friday',
7: 'Saturday'
}
return weekdays[num] || 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'
}
A challenger appears
Equally as elegant as object lookup (though perhaps less readable) is array lookup.
const getDayOfWeekArray = num => {
let weekdays = ['Sunday', 'Monday', 'Tuesday', 'Wednesday',
'Thursday', 'Friday', 'Saturday'];
return weekdays[num - 1] || 'https://www.youtube.com/watch?v=dQw4w9WgXcQ';
}
Limitations
One limitation that comes to mind is say checking an input against a series of comparison operator and/or logical operator statements.
For example, in a function that returns a letter grade given a number input (e.g. 95
), we can check the number against a series of if...else
. if...else
works. Object lookup does not work.
if...else
const getLetterGrade = num => {
if (num >= 90 && num <= 100) {
return 'A'
} else if (num >= 80 && num <= 89) {
return 'B'
} // Rest of the logic
else {
return 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'
}
}
Object lookup
// This simply will not work
const getLetterGradeLookup = num => {
return {
(num >= 90 && num <= 100): 'A',
// Rest of the options
}[num] || 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'
}
Conclusion
As seen above, there are multiple alternatives to if...else
, one of which (guess which one [object lookup]) is superior to if...else
, and vastly superior to switch
.
HOWEVER, object lookup has its limitations in certain situations. It cannot process logical and comparison operators in the key-value pair arrangement objects rely on.