Could someone explain this ternary FizzBuzz?

for(i=1;i<=20;i++) {
console.log(((i%3)?(i%5)?i:'Buzz':(i%5)?'Fizz':'FizzBuzz'));
};

I understand how to use a single ternary operator but this looks like a ternary operator nested within another ternary operator. So I’m trying to understand how it evaluates. I need this broken down step by step if someone could be so kind because it’s really messing with me and I can’t understand it

1 Like

Take it step by step.

Start by taking every block of (...)?, and replacing it with if (...) {. Then replace every : with } else {. You’ll have something like this:

if (i%3) { if (i%5) { i } else { 'Buzz' } else { if (i%5) { 'Fizz' } else {'FizzBuzz'

That’s still kind of a disaster, right? Let’s add in some console.log statements:

if (i%3) { if (i%5) { console.log(i); } else { console.log('Buzz'); } else { if (i%5) { console.log('Fizz'); } else { console.log('FizzBuzz');

And maybe some indentation?

if (i%3) { 
    if (i%5) { 
        console.log(i); 
    } else { 
        console.log('Buzz'); 
} else { 
    if (i%5) { 
        console.log('Fizz');
    } else { 
        console.log('FizzBuzz');

Great! That almost looks like real code! We just need to add a couple of closing braces at the end, and maybe some comments so we can see what’s going on:

if (i%3) {
    if (i%5) { 
        console.log(i);  // i isn't divisible by 3 or 5
    } else { 
        console.log('Buzz'); // i is divisible by 5 only
    }
} else { 
    if (i%5) { 
        console.log('Fizz'); // i is divisible by 3 only
    } else { 
        console.log('FizzBuzz'); // i is divible by 3 and 5
    }
}

And… there you have it.

1 Like

Oh my god, this is so helpful! I finally understand. Thanks so much!!

Wow. That is one obnoxious line of code. (I know it’s not yours @spkellydev and I can certainly see why you were confused by it.)

One would probably never do this, but is a good practice in reading codes. XD
Let’s not worry about what the for loop does, assuming you already know what it does.

Let’s just look at what’s inside the console.
If we slow down and read the code, we can break this down into simple if-else statements.
( i % 3 ) ? ( i % 5 ) ? i : ‘Buzz’ : ( i % 5 ) ? ‘Fizz’ : ‘FizzBuzz’

if( i % 3 ) {                   // The first ? breaks into the first if statement
        if ( i % 5 )  {         // The second ? breaks into the a nested if statement
              i                 // First true condition will reach i
        } else {                // The : breaks into the else
             'Buzz'             // Otherwise it will reach "Buzz"
        }
} else {                        // The second : belongs to the first ?
       if (  i % 5 ) {          // There the second ( i % 5 ) becomes the nested if statement for the first else block
            'Fizz'              // From there it is basically true or false
      else {
            'FizzBuzz'
      }
}

I am not exactly the best at explaining this stuff. Perhaps the diagram would help LOL

I think the code is very difficult to read because it’s designed for how the computer needs it and hasn’t had any consideration for readability. I would code this personally more along the lines of:

var writeFizz = false;
var writeBuzz = false;

if(isDivisibleBy(i, 3)) writeFizz = true;
if(isDivisibleBy(i, 5))  writeBuzz = true;

var response = getResponse(writeFizz, writeBuzz, i);
console.log(response);

function isDivisibleBy(number, divisibleBy) {
return (number % divisibleBy) == 0;
}

function getResponse(fizz, buzz, number) {
if(!fizz && !buzz) return number;

var fizzText = fizz ? 'Fizz' : '';
var buzzText = buzz ? 'Buzz' : '';
return fizzText + buzzText;
}

I cleaned up your code.
You need to use triple backticks to post code to the forum.
See this post for details.

I saw this and couldn’t not comment. There are two goals to writing code, it needs to solve the problem at hand, and it needs to be understandable by other people. Nesting 3 ternary operators in a single line of code fails the second, hands down. ”Clever” code like this is almost never maintainable. AgathaLynn, craigrpears and Cowwy’s solutions are much clearer, more maintainable, and thus more correct than the single line solution. If I was interviewing someone for a job and they wrote that line of code for me, they wouldn’t get it.

1 Like

Is this a JS thing where i%3 is shorthand for i%3 == 0 ?

when a number i is divisible by 3, reminder of the division is 0 (i % 3 == 0 ), otherwise it returns a number greater than 0.

For the statement: if (expression) { action }, action is executed only if expression is true.

when 0 is placed in position where boolean value is expected ( ie in if expression), it is coerced to false.
Positive numbers are coerced to true.

Therefore this code: if (i % 3) can be substituted with:
if (i % 3 !== 0) or
if (i % 3 > 0) or
if ( isNotDivisibleBy3(i) )

1 Like

Wow, great detailed response… I understand it now!
The missing piece was a 0 value being false. I should finish that YDKJS series of books.
Thanks for the help.