DEV Community

Cover image for What The For Loop?

What The For Loop?

Yechiel Kalmenson on June 12, 2018

Learning From A Popular Interview Question This is another post in the genre of technical interview questions I’ve come across during my...
Collapse
 
vitalcog profile image
Chad Windham
if(i & 1)
{
    // ODD
}
else
{
    // EVEN
}

I much prefer bit checks for that sort of thing, and I think it is valuable for beginners to at least know of this option because it opens the door to the concept of bit oriented shortcuts (there are a few worth knowing). Just wanted to add my two cents. But overall really good post!

Collapse
 
sreisner profile image
Shawn Reisner • Edited

Why do you much prefer bit hacking for that sort of thing? Is there a performance benefit or something?

For 99.9% of applications the modulus operator would be a better choice because people understand modulus immediately, and the performance trade-off (if there is one) is negligible compared to the benefit of immediate readability. There's a good chance most people will look at your bit hack and have to Google it or at least pause and think about it for a minute to understand.

That being said, it is a neat trick!

Collapse
 
vitalcog profile image
Chad Windham

Yes, from what I understand the performance is better, though I think in the vast majority of cases it wouldn't matter. Here is a fun read about a real life problem solved with bitwise operations (not simple even odd stuff though...). I primarily mentioned it for the reasons I already stated, it is probably the simplest intro to bitwise operations that I know of, which opens the door for learning more about the language for a beginner. Also, if you have a "use a for loop to find all even odd values" interview problem, and you whip out that solution... Just sayin'

As for the real world webdev readability, I never really considered the &1 thing to be less readable than %2. In my case I had to google both the first time I saw them. AND I'll go as far to say, I have a hard time thinking outside of myself. What I mean by that, is I love seeing new stuff in code and learning what it is/does, so it is hard for me to think in terms of that bothering people (perhaps a weakness on my part). But I do understand the value of human readability over being clever (you can always just minify your code to make it smaller afterwards). But to me both the bitwise and modulus are an abstract symbol followed by a number, and you kinda have to learn what they do when you see them, just part of coding (a part that I enjoy).

But for the most part, I just threw it in the comments because it was a post for beginners and I thought that the target audience might enjoy it. Though I'm glad you commented on the immediate readability aspect, that is worth considering.

Thread Thread
 
kodikos profile image
Jodi Winters

If you're talking optimization, having the if statement (branching) is the most expensive thing, because it requires the processor to dump and reload its entire register state, and kills off the ability for it to pipeline nicely. Getting rid of the conditional is by far the most optimal solution to this code.

Collapse
 
yechielk profile image
Yechiel Kalmenson

💯

In general, I would say optimize for developer time over processor time. Developer time is so much more expensive these days... 😂

Collapse
 
ytjchan profile image
ytjchan

Lazy way:

console.log("1, 3, 5, 7, 9, 11, 13, 15, 17, 19");

(I call it utilitarian)

Collapse
 
yechielk profile image
Yechiel Kalmenson

😂

Though if I asked you for all the odd numbers up to 100 or 1000 your way becomes way more tedious suddenly... 😉

Collapse
 
emilng profile image
Emil Ng

This post is good for learning to delve deeper but risks teaching programmers to write code that tries to be too clever. Unless you're writing a library that needs to be highly optimized the original code will be preferable because the intent is much clearer. Favor clear over clever because someone is going to have to maintain that code down the line.

Collapse
 
yechielk profile image
Yechiel Kalmenson • Edited

True.

That's the problem with many of these technical interviews, they seem to filter for clever solutions over clean, readable, and reusable code, which take very different skills to write.

This goal of this blog post was to help new developers acquire the skills needed to pass the interview. In real life, I would say the general rule is to optimize for developer time over processor time (depending on the situation of course), which means to write code that's easily readable and maintainable by future developers (including yourself).

Collapse
 
emilng profile image
Emil Ng

I agree that there's nothing particularly clever about incrementing a counter variable by two in itself. I was just pointing out the risk of going down the clever code path. If I'm maintaining this bit of code that's part of a larger codebase I would want to see something that shows explicit intent like

for(let i=0; i<=20; i++){
  let isOdd = i%2===1
  if(isOdd){
    console.log(i)
  }
} 

There are other replies to the original post that are clearly going down the clever code path so I think it's worth mentioning.

Collapse
 
bengreenberg profile image
Ben Greenberg

You have a knack for breaking down concepts and really explaining them. Love reading your blog posts. Thanks for this!

Collapse
 
yechielk profile image
Yechiel Kalmenson

Thanks!

Collapse
 
adripanico profile image
Adrián Caballero • Edited

we run a loop for 20 iterations

21 iterations

 
joelnet profile image
JavaScript Joel

extract isOdd out and you can now reuse it elsewhere. It also improves the readability of the for loop.

const isOdd = n => n % 2 === 1

for (let i=0; i<=20; i++){
  if (isOdd(i) {
    console.log(i)
  }
} 
Thread Thread
 
nektro profile image
Meghan (she/her)

isOdd should not need to be a function

Thread Thread
 
yechielk profile image
Yechiel Kalmenson
Collapse
 
_gdelgado profile image
Gio

What if you were asked to do this without a for loop? ;)

Collapse
 
ytjchan profile image
ytjchan

While loop saves the day!

Collapse
 
_gdelgado profile image
Gio

Or better yet ... use some functional programming!

Array(20)
  .fill()
  .map((_, i) => i + 1)
  .filter((num) => num % 2 !== 0)
  .join('\n')
Collapse
 
yechielk profile image
Yechiel Kalmenson

in that case, see some of the other clever comments to the post :)

Collapse
 
oskarlarsson profile image
Oskar Larsson

You can also do

console.log( [...Array(20).keys()].filter(n => {return n%2}).join(', ') )

Probably slower tho.

Collapse
 
mugizico profile image
Jean-Paul Mugizi
 [print(num) for num in range(20) if num % 2 !=0]

and you're done heh #vivapython

Collapse
 
yechielk profile image
Yechiel Kalmenson

But that would make for a much shorter blog post... 😉

 
vitalcog profile image
Chad Windham

oh that's cool to see, thanks for sharing that.
I found this reply post in a stackoverflow thread on the matter

Performance. jsperf.com/modulo-vs-bitwise/8 Bitwise is faster across most browsers (or, it was at the time the answer was posted, in recent Chrome's there is not much difference tbf – danwellman Jan 15 at 9:05

Collapse
 
slackerzz profile image
Lorenzo • Edited
[...Array(20).keys()].forEach((i, e) => {if(e & 1 ) console.log(e)})
Collapse
 
wplj profile image
wplj

is for loop really needed here?

(filter #(not= 0 (rem % 2)) (range 1 21))

 
vitalcog profile image
Chad Windham

yeah, well, I posted it to support what you were showing, not as an argument. It was more just meant to be extra information than anything else.