loading...
Cover image for JavaScript One-Liners That Make Me Excited

JavaScript One-Liners That Make Me Excited

healeycodes profile image Andrew Healey Updated on ・4 min read

Dust off your ternary expressions, we're going in.

One-liners are tricky to maintain (and sometimes even hard to understand) but that doesn't stop them from being cool as hell. There's a certain satisfaction that comes after writing a terse solution.

This is a collection of some of my recent favorites. They will all run in your dev console so pop it open and try them out. I hope you'll share some of your own favorites in the comments!

Calendar Hacking

Ali Spittel tweeted this out recently. It solves a problem I've faced multiple times. If you swap the minus for a plus, it gives you the next seven days.

// Create an array of the past seven days, inclusive
[...Array(7).keys()].map(days => new Date(Date.now() - 86400000 * days));

Random ID generation

This is my go-to function for creating unique ids when prototyping. I've even seen people using it in production in the past. It's not secure but ... there are worse random generation functions out there.

// Generate a random alphanumerical string of length 11
Math.random().toString(36).substring(2);

Quines

A quine is a program that outputs its own source code. Quines have always fascinated me. I've got pretty close to completing my own quines a couple of times in different languages but details are the name of the game.

I've picked some winners for you. Credit to Mama Fun Roll, PleaseStand, and Peter Olson respectively for these three.

// $=_=>`$=${$};$()`;$()
$=_=>`$=${$};$()`;$()

// eval(I="'eval(I='+JSON.stringify(I)+')'")
eval(I="'eval(I='+JSON.stringify(I)+')'")

// For those who like their quines via alert
// (function a(){alert("("+a+")()")})()
(function a(){alert("("+a+")()")})()

Scrape query parameters

Talk about non-maintainable code. This converts the page's query parameters to an object in 78 bytes. Thanks Alex Lohr for code golfing it (and 齐翊 too).

?foo=bar&baz=bing => {foo: bar, baz: bing}

// Set the current page's query parameters to `q`
q={};location.search.replace(/([^?&=]+)=([^&]*)/g,(_,k,v)=>q[k]=v);q;

I'd like to see a minifier work that hard.

Working clock

With a sprinkle of HTML, you can create a working clock with source code you could read out in one breath. I wrote this after a challenge from a co-worker. It ticks every second, updating the page with the current time.

<body onload="setInterval(()=>document.body.innerHTML=new Date().toGMTString().slice(17,25))"></body>

Shuffle an array

Until Pythonistas show up with their import random, random.shuffle(array) solution, we're going to enjoy what we have. This has the bonus of having an infinitesimal chance of being an infinite loop (implementation depending). Michiel Hendriks helped us save a few characters here πŸ‘. Don't use in production.

// Return a shuffled copy of an Array-like
(arr) => arr.slice().sort(() => Math.random() - 0.5)

Generate random hex code

ES7's padEnd is a blessing. Along with padStart, they've made number to string conversions that much easier. Writing hex values right into JavaScript code is always pretty neat too.

// Generate a random hex code such as `#c618b2`
'#' + Math.floor(Math.random() * 0xffffff).toString(16).padEnd(6, '0');

Pass the interview in style

The infamous interview question answer but codegolfed. I researched and I don't think it can get any shorter than this.

for(i=0;++i<101;console.log(i%5?f||i:f+'Buzz'))f=i%3?'':'Fizz'

Remove duplicates

This only works with primitives but it's still nifty. Set takes any iterable object, like an array [1,2,3,3], and removes duplicates. The spread operator makes that set [1,2,3].

// Remove duplicates from the iterable `arr`
[...new Set(arr)]

A keyboard so real you can taste it

Okay, I don't really count this as a one-liner but it's too good not to include. A masterful codegolf solution by edc65. It's terse to a fault and codegolfed within an inch of its life but we should bask in its glory.

// Return a ***3D*** ASCII keyboard as string
(_=>[..."`1234567890-=~~QWERTYUIOP[]\\~ASDFGHJKL;'~~ZXCVBNM,./~"].map(x=>(o+=`/${b='_'.repeat(w=x<y?2:' 667699'[x=["BS","TAB","CAPS","ENTER"][p++]||'SHIFT',p])}\\|`,m+=y+(x+'    ').slice(0,w)+y+y,n+=y+b+y+y,l+=' __'+b)[73]&&(k.push(l,m,n,o),l='',m=n=o=y),m=n=o=y='|',p=l=k=[])&&k.join`
`)()

It prints:

Amazing.


Join 150+ people signed up to my newsletter on programming and personal growth!

I tweet about tech @healeycodes.

Posted on by:

healeycodes profile

Andrew Healey

@healeycodes

πŸ“š 🌡 πŸ• Love blogging, open-source, and helping out. https://healeycodes.com

Discussion

pic
Editor guide
 

I've got another good one to create arrays of a specific size and map over it at the same time.

Array.from({length: 3}, (val, i) => i)
// [0, 1, 2]
 
[...Array(3).keys()]
// [0, 1, 2]
 

Oh SHID.
This is exactly what I needed so many times, and it finally seems like it's a performant approach?!

 

It looks quite clean and sleek, so I decided to test out the performance on my pc

Weirdly using Array(N) is about 20% faster than using an array-like {length: N} when used inside Array.from()

I also added comparisons of mapping as a parameter vs (dot)map too.

Wow, that's... humbling.
BTW, you could beat out ForLoop with:

const arr = new Array(100)
for (let i = 0, i < 100, i++)
  arr[i] = i

since the size is known in advance.

 

You can shave off one more char for your hex color code generator without resorting to padEnd:

// before
'#' + Math.floor(Math.random() * 0xffffff).toString(16).padEnd(6, '0');

// after
'#' + (0x1000000 + Math.random() * 0xffffff).toString(16).slice(1, 6);
 

A clever change. Probably faster too?

 

Thanks. Not sure if it's faster, but that's usually a non-issue for code golfing :)

 

Awesome! Close to what I expected πŸ‘

 
// I'd like to see a minifier work that hard.
document.location.search.replace(/(^\?)/,'').split('&').reduce(function(o,n){n=n.split('=');o[n[0]]=n[1];return o},{});

// Challenge accepted.
location.search.substr(1).split('&').reduce((o,n)=>{n=n.split('=');o[n[0]]=n[1];return o},{});

I'm not a big Javascript person so I don't know what the difference is between window.location, document.location and just location (which I assume uses the global window context). I know substr works fine on an empty string, and I'm making the (heroically cavalier) assumption that query strings start with a ? in all browsers' implementations of location.search.

But both of these return something incorrect if there's no query string:

{"": undefined}

Oops. Well, we can do something about that:

(() => {let x=location.search.substr(1).split('&').reduce((o,n)=>{n=n.split('=');o[n[0]]=n[1];return o},{});delete x[""];return x})()

And now it's longer and even less maintainable, but hey :)

 

This is brilliant, Ben! πŸ˜„

 

I can probably do it in even less characters... let me try:

q={};document.location.search.replace(/([^?&=]+)=([^&]+)/g,(_,k,v)=>q[k]=v);q;

Hey, that one could not accept empty value (eg:'?a=&b=1&c=')
try this instead:

//keys should not be empty, but value can
q={};location.search.replace(/([^?&=]+)=([^&]*)/g,(_,k,v)=>q[k]=v);q;
 

Awesome one liners... Until you hit save and Prettier formats it to two 🀣

 

Be careful with that shuffle, it won’t yield truly random results because sort expects its comparator to uphold Math.sign(compare(a, b)) === -Math.sign(compare(b, a)). Microsoft once screwed up by using exactly that.

 

What an interesting story! Thanks for sharing.

And yes, for any production code just use Fisher/Yates!

 

Does this count? 😈

{
    "precommit": "git ls-files | while read -r FILE; do if file \"$FILE\" | grep -q \"text\"; then vim --clean -n -e -s -c \":%s/\\s\\+$//e|:retab|:wq\" \"$FILE\"; fi ; done"
}
 

I'll allow it! πŸ˜€

 

It's a shorthand for returning one of three colors if the score is truthy. Otherwise it returns a fallback value.

score => ({1: "#98FB98", 2: "#FFFF99", 3: "#FA8072"}[score] || "#DCDCDC")
 

that can be even more minified:

score => (["", "#98FB98", "#FFFF99", "#FA8072"][score] || "#DCDCDC")

you could lose the first array item and use score - 1, but that would have more characters.

 

Would it? Wouldn't you shorten by 4 chars to remove "",, or 3 if whitespace doesn't count, and only add 2 chars to go from [score] to [score-1]? Seems like it'd still be shorter by at least a character, or am I missing something?

 

There are a lot of byte saving tips one can employ in code golfing. A nice collection can be found here: github.com/jed/140bytes/wiki/Byte-...

 

The one I recently discovered as very useful, mostly while testing or mocking API calls:

await new Promise((resolve) => setTimeout(() => resolve(1), 2500));

Usually I use, when I have to simulate data fetching ;P

 

Very cool! Thanks for sharing Dominik πŸ‘

 

Thanks! I would recommend adding most of them to vscode snippets. It's really easy to use just like typing "sleep" + enter and I have ready one-liner in my code ;)

 

Why waste all those extra characters, this also works

(arr) => arr.slice().sort(() => Math.random() - 0.5)
 

Nice find, thanks! Edited πŸ‘.

 
isInRange = (a, b, c) => [...Array(c - a +1)].map((e, i) => i + a).indexOf(b) !== -1

I did this one for a challenge. It finds if a number is in a range of two other numbers so find if b is in range of a to c

 

Wouldn't you just check b >= a && b <= c ?

 

That was definitely a way to do it. However, I am pretty sure that only works with constraints on the range values, and the way I wanted to solve it was to be sure it could handle any range.

I could be wrong which in that case, I will certainly remember this way lol

Nope to me lol, you're just right and I am pretty sure that works for any size range not just that but the
Big O is significantly better ahahaha!

 
q={};location.search.replace(/([^?&=]+)=([^&]+)/g,(_,k,v)=>q[k]=v);q;

got a problem like this:

'?a=&b=1&c='  ----> {b: 1} 

lost key 'a' and 'c'

solution: replace the 2nd '+' by '*'

q={};location.search.replace(/([^?&=]+)=([^&]*)/g,(_,k,v)=>q[k]=v);q;
 

Thanks! Fixed it :)

 
const makeMockingSpongebobMeme = (someString) => (typeof someString === "string" ? someString : "Wrong input").split("").map(a => Math.random() > 0.5 ? a.toLowerCase() : a.toUpperCase()).join("")

One of the intriguing trait of functional programming is to look unreadable despite being working.

 

I use Set often to remove duplicates, but I didn't know it's possible to use the spread operator on a Set.

I have been using Array.from(new Set(myArray)) until now. Since Array.from take an iterable I could have guessed but...

Nice post !

 

Glad it helped ya!

 

//only rounds up 15 can be changed to what ever number you want to use
roundMinutes = (mins) => { return (~(mins / 15) * 15) * -1 ; }
roundMinutes(35) -> 45
// will now round down instead of up
roundMinutes = (mins) => { return (~~(mins / 5) * 5) ; }

 
const r = {valueOf: Math.random}

Not really a one-liner, but good for when making generative art.

 
[deleted]
 

great stuff
thanks

 

Please don't use code in production that multiplies 86400000 (24*60*60*1000) for computing dates; date/time is way more complicated than that, you will shoot yourself in the foot. Use a library.

 

A keyboard so real you can taste it

Love it!

 

This article makes JavaScript look really fun to play with. Thanks Andrew!

 

Yeah, this one was fun to write! 😁

 

Good stuff thanks!!

 

google search got me here. Thank you for this article. This one's i've been looking for.

 

Note that list shuffle approach has a bunch of bias and doesn't perform very good shuffling. See beesbuzz.biz/code/6719-How-not-to-... for a detailed explanation.

 

Yup! πŸ˜€ The function is short but scary. Raphael linked another article that covers the same topic. I'll add a note.

 

A couple of comments!

Anything that has semicolons in it isn't a one-liner, no matter how you try to stretch the definition.

And does it matter that days aren't always 86400000 milliseconds long?

 

I like it a lot.

 

Now I need the bash (or if Apple forces me zsh) script so I can call the command sevenDays ;)