DEV Community

Cover image for 9 Neat JavaScript Snippets For Algorithms And More
Mike Cronin
Mike Cronin

Posted on • Originally published at Medium

9 Neat JavaScript Snippets For Algorithms And More

Knowing certain JavaScript one liners can save you valuable time while developing or interviewing. Here are some of my favorite “once you know, you know” snippets that I have actually used while coding. Only one of them is a bit code golf-y, and unsurprisingly it uses reduce.

Wrap around a list

Spinning is a neat trick, but so is wrapping. A lot of times in algorithms you will need to wrap around a list. Meaning move a number of spaces, and if you reach the end of the list, go back to the first index. So if a list is 8 values long, but you have to move 10, you would need to land on the second index. You could use a bunch of complicated if statements, OR…

const wrap = (arr, steps) => arr[steps % arr.length];
wrap(['a','b','c'], 0) // a 
wrap(['a','b','c'], 1) // b
wrap(['a','b','c'], 2) // c
wrap(['a','b','c'], 3) // a 
// etc ...
Enter fullscreen mode Exit fullscreen mode

You can implement this differently based off steps, but the key thing to understand is the modulo. It’s a handy little operator, keep it in mind when looking at “overflow” type problems like this.

Log a variable with its name

This is such a great trick when debugging. Thanks to object shorthand notation we can log out variables with names by default.

const someVar = 1;
console.log({ someVar });
// logs out { someVar: 1 }
Enter fullscreen mode Exit fullscreen mode

If you put in a bunch of logs (and you totally will when debugging), it can be hard to keep track of which is which with all the asyncs, fetches, and loops flying around. Instead of having to take the time to type multiple args like console.log('some var', someVar), toss in some curly brackets and call it a day.

Optional properties in objects

If you don’t want properties pointing to undefined or null , you might use some if statements to optionally add properties:

//...
const obj = {
  a: 'whatever',
};
if (b) {
  obj.c = 'ok';
}
return obj;
//...
Enter fullscreen mode Exit fullscreen mode

However, it’s verbose and I’ve always hated it. It may be clear, but it’s clunky. Well, thanks to object spreading, it’s a thing of the past:

return {
  a: 'Whatever',
  ...(b && { c: 'ok'}),
};
Enter fullscreen mode Exit fullscreen mode

We can use a spread and && logical short circuiting to dynamically check whether or not to add the property by spreading it. This comes most in handy when you just want to return an object, and don’t want to create a temporary variable.

Sleep in JavaScript

A few times I had to deal with a terrible API that was slow and didn’t have a hook to say when it finished. So, we just had to wait a second to make sure it loaded. We also wanted to use promises instead of setTimeout callbacks, so using a sleep function was ideal. We could simply await for a second and then move on. No need for callbacks!

const sleep = (ms) => new Promise(r => setTimeout(r, ms));
Enter fullscreen mode Exit fullscreen mode

Here’s how to promisify setInterval as well.

Swap variable values

Before modern JS, if you wanted to switch the values of two variables, you’d have to introduce a 3rd ‘temp’ value. Now that we have array destructuring and assignment, we can do it in one line:

a = 10;
b = 5;
[a,b] = [b,a];
// a is 5, b is 10
Enter fullscreen mode Exit fullscreen mode

Round to nearest 10, 100, 1000…

This one is useful in algorithms if you need to rough out numbers to various levels. Basically, what you’re doing is dividing first to move the decimal up. With the “useless” numbers now decimals, you can round them off. To get the number back up to its desired size, you multiply it. The ignored numbers now become zeros. It’s a neat trick for dealing with money or logarithm-like scales where after a certain point, small numbers can be rounded off.

const rounder = (val, place) => Math.round(val / place) * place;
rounder(1549, 100); // 1500
rounder(15590, 1000); // 16000
Enter fullscreen mode Exit fullscreen mode

Remove duplicates with Set

I just wrote about Sets, and apparently this is kind of their only use. If you have an array and you want to remove the duplicates, you can do so with a Set.

const val = [...new Set([1,2,1,3,1,4])];
// [ 1, 2, 3, 4 ]
Enter fullscreen mode Exit fullscreen mode

Don’t forget to spread the new Set back into a regular array. Note: be careful with massive lists, as this may not be the most performant solution.

Count character instances

If you have an array (or array from a string) and want to know how many times characters appear, there’s a super slick way to do this with reduce.

const charTotals = (arr) => arr.reduce((totals, char) => ({ 
  ...totals, [char]: (totals[char] || 0) + 1, 
}), {});
charTotals('Hi there!'.split(''));
// { H: 1, i: 1, ' ': 1, t: 1, h: 1, e: 2, r: 1, '!': 1 }
Enter fullscreen mode Exit fullscreen mode

This one might not be all that useful, but there are 2 techniques that I want to make sure you know: dynamic object properties and implicit returns with an object. Both of those things are crucial knowledge, and if you don’t understand reduce, then read this.

ID maker/counter

I think I needed to dynamically create non-db temp ids for react components and squished a classic counter into one line. Each time the function is called, the counter increases, and no other function can alter its internal state. It uses a closure, Immediately Invoked Function Expression, and a default value to keep things tight.

const counter = ((num = 1) => () => num++)();
counter() // 1
counter() // 2
counter() // 3
Enter fullscreen mode Exit fullscreen mode

Also bonus tip to use default values in function parameters to avoid needing a new line. And you can stop making it an IIFE if you actually want to make the starting number dynamic:

const startCounter = (num = 1) => () => num++);
const counter100 = startCounter(100)
counter100() // 100
counter100() // 101
counter100() // 102
Enter fullscreen mode Exit fullscreen mode

A word on readability

Look, I’m all about readable code and I’ll be the first person to say that some of these snippets aren’t super straightforward. What you get in brevity you lose in readability. Now, personally, I don’t think any of these are too wild, but others might disagree. That’s why you should try to use small, named functions and descriptive variables. These pieces can be the crucial tip to help your code click for others. But, ultimately it comes down to what you and your team like, so feel free to modify or expand anything here. And if you have any clever one liners you love, please show them off in the comments!

happy coding everyone,

mike

Top comments (8)

Collapse
 
mostlyfocusedmike profile image
Mike Cronin

You totally can! The reason I didn't bother is that ?? is for maintaining things that might be falsy but not undefined or null. Since I know in this object that it's always going to be undefined or a non-zero Number type, || is fine. BUT, I'm very glad you commented because the point of this article is to expose new ideas! So for anyone reading this, Nullish Coalescing operator is absolutely clutch and you should check it out

Collapse
 
nazareth profile image
َ

Self documenting code > neat shortcuts.

“It’s harder to read code than to write it.” — Joel Spolsky

I would say if you do end up writing this, you should most definitely include more comments to explain it.

return {
a: 'Whatever',
...(b && { c: 'ok'}),
};

Collapse
 
mostlyfocusedmike profile image
Mike Cronin

Ah man this one truly walks the line for me between readable advanced vs flashy over compensation. The main reason I included it is because it is literally like 10 characters long and if you know what short circuiting and spreading are, it makes total sense and you hopefully you go "ah, that's pretty clever." That was my exact reaction, personally anyway. I think the other reason I like it so much is that I just can't get over how clunky the if statement alternative is.

If the cost of using this is just ...(b && { c: 'ok'}), // optionally add this obj or some other little comment, no problem. I definitely think modern coding can use more comments. I honestly wonder if this optional pattern will go the way of destructuring, which was originally confusing but now an essential skill, or reduce which it seems most people decided wasn't worth the brevity and shouldn't be used.

Collapse
 
dcsan profile image
dc

With your code to generate IDs won't that break the react rendering if the ID is generated differently each time? I thought the point was that the key for component is derived from the actual data so that it is always going to be the same key for the same item in a list or whatever?

Maybe a few components are always called and rendered in the same order so then you get lucky and the counter for the key always returns the same value for the same invocation?

Collapse
 
mostlyfocusedmike profile image
Mike Cronin

No you're right, that would be a problem (and technically why we shouldn't use the map index as a key). That's not quite how it was used. Say you had real entries from a db like:

{ 
  id: 132,
  name: 'Tom',
  age: 31
}
Enter fullscreen mode Exit fullscreen mode

When mapping through them after fetching, you could use the ID as a key, since it should be unique and unchanging to its owner. My issue was, I was generating multiple items on the frontend BEFORE saving them as a batch. So that meant there was no id from a DB yet. So i just wanted a pre-id that was created with the object and didn't change. I used the counter method on initial generation, not iteration. Does that make sense?

Collapse
 
mostlyfocusedmike profile image
Mike Cronin

Also, yesterday what I used the counter for was making sure at least 3 resources had loaded onto a page. I didn't care in what order, just that 3 had loaded. So I used the counter on each load event, and once it hit three, any one of them could trigger the next function, but only one of them ever would. I thought that was neat.

Collapse
 
jashgopani profile image
Jash Gopani

Liked the conditional object properties snippet and got to learn dynamic property syntax which I thought didn't exist. Thanks! ✨

Collapse
 
mostlyfocusedmike profile image
Mike Cronin

I'm so glad it showed you something new! This article was designed to show people new concepts that they may not have run across yet