r/javascript • u/smellycode • Mar 02 '19
Useful javascript one-liners.
https://medium.com/@smellycode/js-one-liners-8bc0a6af2345?source=friends_link&sk=a9295a05aef9e514e137fca7eeb89cd16
Mar 02 '19 edited Mar 02 '19
The last one fails when the random number is smaller than 0x100000. You need to add .padStart(6, '0') at the end to make sure it's 6 characters.
I've also used Math.random().toString(16).slice(-6) to generate random hex colors. There is a very low chance of getting not enough characters and the distribution is pretty uniform, but still not completely safe.
3
2
u/BluudLust Mar 03 '19
Wouldn't this cause an issue with distribution of colors doing it this way instead of using 3 randoms?
1
Mar 03 '19
The second method might have very minor issues, but the first is always uniformly distributed. Each of the 24 bits should have equal chance of being 0 or 1, because if you had to pad the 0's, it means the 24 bit integer actually did have at least four 0's at the start, which happens 1/16 of the time.
1
u/BluudLust Mar 03 '19
Really it depends on how uniform the pseudorandom number generator is. For all intents and purposes it's the same, but technically speaking 3 random numbers will be a far more uniform distribution than using one.
4
Mar 02 '19
Nice article.
But using images to post code doesn't seem like a good idea.
2
u/smellycode Mar 02 '19
Thank. :)
I have added a link of gist in the end. Next time I'll try to avoid them.
2
u/theibbster Mar 05 '19
It's an issue of accessibility too, people with screen readers won't be able to read the code
7
u/frankandsteinatlaw Mar 02 '19
I’m not sure if the “one-liner” lens is all that useful. I think you’ve presented some useful bits of code here but having the code be one line or two lines or three shouldn’t really matter. I’d personally rather see lists like these themed by functionality vs arbitrary line count, especially when some of the examples become harder to read due to this restriction.
4
u/smellycode Mar 02 '19
Agree. I have tried to shed some on this in the conclusion section.
2
u/frankandsteinatlaw Mar 02 '19
Ah, admittedly I skimmed the examples. Glad to hear you speak on this.
3
3
u/codewizrd Mar 02 '19
What’s your editor setup? Colorscheme, etc?
3
u/smellycode Mar 02 '19
I use Fira Code fonts with ligature https://github.com/tonsky/FiraCode. The theme is Blackboard. The tool I used it Carbon https://carbon.now.sh
43
u/Shaper_pmp Mar 02 '19
Why on earth would anyone use a font for programming that runs characters together and makes it difficult or impossible to determine whether something is a double- or triple-equals?
With a language like JS that's just asking for trouble...
16
u/smellycode Mar 02 '19
I have been using Fira Code since last one year cause it's really good alternative to Operator Mono. I have never run into any problem. Indeed, I am loving it so much that every freaking editor I use both web/desktop I use with Fira Code.
-1
56
u/Microwawe Mar 02 '19
I'm not a fan of firacode either but the === has three horizontal lines whereas the == has only two so it's not that impossible to tell them apart.
18
u/deadcow5 Mar 02 '19
Personally I like the font (I use it myself), but I would probably not use it for screenshots intended for distribution. Too many people are gonna ask how to produce a triple bar equals, or WTH that even means.
21
u/Voidsheep Mar 02 '19 edited Mar 02 '19
The point of ligatures is to improve readability, because things commonly expressed by different combinations of characters get unique symbols.
=> <=The two above look either like arrows to right and left, or comparisons with equal or lesser/greater.
⇒ ≤The two above clearly have nothing to do with each other, one being an arrow to right and one being mathematical operator for "less than or equal".
Of course everyone will just learn what different characters mean together, but ligatures make the difference more explicit when you write and scan code quickly. In the specific case of strict/loose equals operators the benefit isn't that obvious, but it's still easy to tell them apart.
-10
u/Shaper_pmp Mar 02 '19 edited Mar 02 '19
Ligatures are fine, but like any tool they're only useful when they're useful.
Any font that's intended for programming that runs together arbitrary sequences of characters in a way that makes it difficult/impossible to tell at a glance how many there are, however, seems self-evidently sub-optimal... especially in cases where it's the difference between things like type-coercive- and strict equality.
Edit: I just noticed that the triple-equals glyph actually has three lines not two, so it's a little easier to tell them apart than I first realised.
That said, the fact it wasn't necessarily easy to tell whether it had two or three horizontal lines on a mobile screen kind of makes the same point in a different context...
6
Mar 02 '19
Any font that's intended for programming that runs together arbitrary sequences of characters in a way that makes it difficult/impossible to tell
They aren’t “arbitrary sequences” of characters at all, though. They are specifically chosen to make specific code sequences less ambiguous or otherwise easier to read at a glance. In my opinion, that is far more important than knowing how many characters there are in a particular sequences at a glance (which honestly seems like a pretty arbitrary criterion by which to judge a font “sub-optimal”).
1
u/Murdathon3000 Mar 03 '19
the fact it wasn't necessarily easy to tell whether it had two or three horizontal lines on a mobile screen kind of makes the same point in a different context...
Yeah, that might be an issue that the minority of people have, it's not very difficult to see that there are 3 lines. Here's an example,
ll
lll
Did you catch it?
-10
10
u/careseite [🐱😸].filter(😺 => 😺.❤️🐈).map(😺=> 😺.🤗 ? 😻 :😿) Mar 02 '19
Because it's not an issue because of the ligatures you dislike. Double == are easily discernible.
2
5
u/taniket Mar 02 '19
If you are using double = rather then triple, there's something wrong with your code other than the font.
-1
u/benihana react, node Mar 02 '19
that's great in theory and all. but in practice, on the web, a lot of values get coerced to strings, so it's not really that straightforward.
sometimes you have to deal with the fact that something that is represented as
35in your database will be represented as"35"in your UI. Using strict equality will lead to subtle bugs in these kinds of situations.8
u/folkrav Mar 02 '19
There's something wrong with your architecture if you're straight up comparing DB and UI values. For the odd time these things happen, I still much prefer to go with strict equally and cast manually. It's much easier to reason with, and easily testable.
-3
u/Shaper_pmp Mar 02 '19 edited Mar 02 '19
Not at necessarily - are you arguing against the entire concept of type-coercion here, or just claiming that there are always better ways to use it than testing for loose equality with
==?2
u/adenzerda Mar 02 '19
I’m not the person you’re replying to, but personally I haven’t used explicit loose equality in years. Might be a symptom of working in a c# house, but it seems like each time I used to use it, it felt like it could have been done in a less sloppy way.
Exceptions, of course, granted to our humble friend
if (!thing) { }(I know it has its own shortcomings to be conscious of but it’s usually fine)0
u/Shaper_pmp Mar 02 '19 edited Mar 02 '19
You've never had a situation where a value can be a positive integer, 0 or null (say, retrieving the count of some resource via an async computation), and you only care if it's an integer greater than zero... or any other similar example of trinary logic (true/false/null)?
if (!thing)is just one example of a general class of problem, and you can only avoid the==if you happen to be coercing to boolean (not other types) and if you're comparing to a static value (rather than another variable).Edit: Or a better example, say involving the result of an async operation that can return
trueorfalse, wherenullmeans "pending" when the operation hasn't yet completed:if(asyncResultThatCanBeTrueFalseOrNull == thingThatCanBeTrueOrFalse) { // do something where we treat false and null the same }2
1
u/izuriel Mar 03 '19
It takes time to get familiarized with it, I’ll give you that. But IMO in the long run it enhances readability*.
As has been stated already triple equals has three bars vs two for double equals. Very distiguishable. Also not equals has a line through making it stand out as well. There are some ligatures I’m not as much a fan of (like less equal and greater equal being angled). For symbol heavy languages like Haskell this is a massive boost in readability there given the symbols used.
there are some odd cases in languages where symbol combinations are nonstandard and fall apart with ligatures.
1
Mar 03 '19
Er. The triple equals has three lines. The double is twice as wide as it is high. The single is near-square.
Incidentally, I use Firacode, and love how it makes certain multi-character operators unambiguous.
1
Mar 03 '19
I use glyphs all the time. But I agree with you on one level - folks should just make gists to save the confusion.
1
u/FanOfHoles Mar 03 '19
It works when you have eslint take care of complaining about double equals. Still, I tried a few times and always quickly went back to Consolas, which does not have ligature support.
1
u/ghillerd Mar 02 '19
It's actually not at all difficult to tell the difference between a == and a === in firacode. I bet of you ran a test of someone who's used it for a day, and asked them to glance at code and tell you if it used double or triple they'd have a 100% success rate.
-7
Mar 02 '19
Cause its "hipster cool". After all, its JS.
7
Mar 02 '19
How on Earth does font ligature have anything to do with JavaScript in any imaginable way??????
-6
Mar 02 '19
Font ligature per se? Nothing.
Font ligature in code? Everything.
3
1
u/izuriel Mar 03 '19
I got into ligatures for Haskell and Elixir. So your argument is null and void.
0
Mar 03 '19
Haskell and Elixir
Ah well, see!
1
u/izuriel Mar 03 '19
See what? Are you saying that Haskell and Elixir are just JavaScript? Or are you lashing out due to not having fully grasped any of the three languages so your first choice is to insult anyone who can?
-7
0
Mar 02 '19
[deleted]
7
u/haykam821 Mar 02 '19
You know you can just
require("https://cdn-images-1.medium.com/max/2600/1*Y2FfIZMchiawzRIS_Rfrcg.png"), right?That'd be a horrible future and an awesome joke package: importing code by detecting text in an image
3
u/smeijer87 Mar 02 '19
const ocr = require('ocr') ; const img = await fetch('http://...png'); const code = ocr.parse(img); eval(code);Something like that? I'm pretty sure it would be possible. We only need someone to create a jsfiddle.
6
u/Drugba Mar 03 '19
I absolutely love [...new Set(arr)] for removing dupes from an array of primitives. That being said, if I was using it in a shared codebase, I'd be sure to add a comment explaining it as I don't think it's super clear at first glance.
1
u/sharlos Mar 03 '19
You could wrap it in a function spelling it out maybe?
2
u/Drugba Mar 03 '19
Totally could. Personal preference, I'm not a fan of single line functions, but yeah, you totally could make a removeDupes function.
1
u/drowsap Mar 03 '19
Why not have it as a Set to being with instead of an array? If it’s the way that the data returns from the server, then dedupe there?
1
u/billymcnilly Mar 03 '19
I found myself writing a comment for this just the other day! But then I decided to use a variable name instead of a comment.
const deduped = [...new Set(allValues)]Do you think that's descriptive enough?
3
u/Danieliverant Mar 02 '19
I would add "group by" using reduce function. I'm on my phone but you can find it on google - a real one line useful function.
2
u/Danieliverant Mar 02 '19
From stackoverflow: (xs, key) => xs.reduce( (rv, x) => (rv[x[key]] = rv[x[key]] || []).push(x) , {});
(I've just converted it to arrow functions - maybe I forgot some brackets)
1
u/smellycode Mar 02 '19
I'll add it asap. Thanks for the suggestion.
-1
5
u/lordxeon Mar 03 '19
I too can write unreadable JavaScript as one line. In fact I have built entire websites in one line of JavaScript!
These are (mostly) unreadable messes that say “I’m smart and won’t be working here when shit breaks”
2
u/Pavlo100 Mar 02 '19
removeDuplicates only removes duplicates if they are primitives. if you use an object as parameter then it will fail
1
u/smellycode Mar 02 '19
Well, you need to define the definition of duplicates. :)
const a = {a: 'A'}; const b = a; const c = {...a}; const array = [a, b]; // contains duplicate. a and b are duplicates. const array = [a, c]; // does not contain duplicate. a and c are two different objects, albeit they have the same structure.-1
u/Pavlo100 Mar 02 '19
duplicates are when they have the same structure, a and c is a very normal use case, in this case you would like to remove c
2
u/smellycode Mar 02 '19
if that is the case then this might help.
const removeDuplicates = arr => arr.filter((item, index) => index === arr.findIndex(v => isEqual(v, item)));
isEqualcan be your own or 3rd party comparator function. Here's one naive implementationconst isEqual = (a, b) => typeof a === 'object' && typeof b === 'object' ? JSON.stringify(a) === JSON.stringify(b) : a === b;Hope this helps.
0
u/Pavlo100 Mar 02 '19
JSON.stringify({identifier: 5, version: 2}) === JSON.stringify({version: 5, identifier: 2}) // falseSame structure, different order
All i am saying is that you should specify what the function works on.
The function works great on strings and numbers.
2
u/smellycode Mar 02 '19
I didn't know that the order of keys matters when we stringify. Thanks for pointing it out.
2
u/LookingForAPunTime Mar 02 '19
If you care about strict object equality, perhaps you should use an immutability library such as Immutable.js
It won’t completely prevent duplicates instances, but it can greatly reduce the need for deep object equality checks.
1
u/adenzerda Mar 02 '19
Nice article.
I’ve heard the spread operator is still slow. Is this true, and if so, when does it become noticeable compared to other methods?
0
u/smellycode Mar 02 '19
Thanks. :)
I also heard that it's bit slow but I think browser vendors are working on it. Here's the performance plan https://docs.google.com/document/d/1EA9EbfnydAmmU_lM8R_uEMQ-U_v4l9zulePSBkeYWmY/edit
IME, I have not seen any performance glitch yet. May be that's because of babel-transpiling. In case, if I find any pertaining link/doc, I'll share it.
3
u/hypercurrency Mar 02 '19
Merge arrays. Why wouldn't you just do:
MergedArray = [...Array1, ...Array2];
-2
Mar 02 '19
That works, but only for explicitly named arrays. What about the generalized case?
3
u/hypercurrency Mar 02 '19
I don't know what the generalised case you're referring to? 😐 I'm sure that I am missing something. I am no expert but anytime I've needed to merge arrays, that's what I do.
0
Mar 02 '19
Oh, I see. What if you want to merge a bunch of arrays? By the generalized case, I meant something that would work for any number of arrays including no arrays at all.
Using OP's merge function `const merge = (...arrays) => [].concat(...arrays)`, you can merge `[], [1], [1,2], [1,2,3], [1,2,3,4]` without having to give a name to each array. What if you have 100 arrays?
4
u/LookingForAPunTime Mar 02 '19 edited Mar 02 '19
[...[], ...[1], ...[1, 2], ...[1, 2, 3], ...[1, 2, 3, 4]]But more to the point, you’re not going to have an “unnamed” array. Literally anything you don’t write by hand is going to have a reference of some kind, and you can spread it, even if you need to wrap the spread in round brackets.
And if you have an array of arrays, there’s
Array.prototype.flat().
2
u/marocu Mar 02 '19
Bookmarked, thanks!
2
u/FanOfHoles Mar 03 '19 edited Mar 03 '19
Does that actually do anything for you? I realized a long time ago that "bookmarking" for me means "put away and forget forever".
What I do now is this: Either something is worth reading and committing to memory (in a meta form, whatever the brain makes of it over time) or I may as well just close that browser tab. Even code samples - whenever I need(ed) something I just create it from scratch, maybe with the help of some googling. If you have bookmarks you would need to figure out, after years, which ones are actually relevant, a quick Google search and some thinking probably is faster (and a lot more fun than going through lot of bookmarked sites).
1
-5
u/BinxyPrime Mar 02 '19
You can do almost all of these in one line with lodash and its probably optimized better
11
u/Shaper_pmp Mar 02 '19
... at the cost of an additional external dependency for your project.
3
u/MakiBM Mar 02 '19
Which might be in your favor at this example. Things that are used often are better when standarized. It's cool wyen you hire a dev and he knows your tooling. You will end up having less code because there are bits to import and reuse rather than writing it from scratch. And you will have that exposed as a package for your project which barely happens when you drop one liner here and there as you go. Using tools like that helps in project maintaince, onboarding etc...
Dependencies are as good as your review process. You could stick to vanilla and let go react / vue / you name it - even if your custom solution would beat popular frameworks (but lets be realistic, this doesnt happen that often) you would end up creating big overhead for new members and need to wait for months for productivity to come... Its all about common language and making development comfortable.
4
u/Shaper_pmp Mar 02 '19
Things that are used often are better when standarized. It's cool wyen you hire a dev and he knows your tooling. You will end up having less code because there are bits to import and reuse rather than writing it from scratch.
Absolutely true, though you won't get much more standard, accessible and "less code" than using standard language features. ;-p
More seriously though, I'm not arguing against using dependencies. I'm arguing adding dependencies is not a cost-free action, so "lol just use Lodash" is advice that is only contextually useful in some situations - in others it could be a terrible idea.
2
2
u/greymalik Mar 02 '19
But when I’m interviewing for a job and they ask me to dedupe an array on the whiteboard they’re not going to like _.uniq as an answer. It can be good to know the bare metal way to do things.
3
2
u/BinxyPrime Mar 02 '19
They probably wouldnt really love the n squared brute force one liner either though
-7
u/98ea6e4f216f2fb Mar 02 '19
This is not a one-liner. Also it's very un-idiomatic javascript. If you're going to line break, then use a curly brace.
5
u/smellycode Mar 02 '19
98ea6e4f216f2fb
You are right. This is not a one-liners. I added it to complete the `flatten` with any level. Prolly I should add one line which tells it's not one liner.
Adding curly braces to line break is personal preference. :)
8
u/ShortSynapse Mar 02 '19
It should be noted that we now have the native Array#flat() method.
[[1,2],[3,[4,5]]].flat(Infinity) // [1,2,3,4,5]1
Mar 02 '19
Ah I had no idea about passing an argument to it, and
Infinityis very clever, thanks for this.1
u/haykam821 Mar 02 '19
Infinityis too clever. Try this instead:const flatInfinity = arr => { while (true) { if (arr.some(item => Array.isArray(item))) { arr.forEach((item, index) => { if (Array.isArray(item)) { arr.splice(index, 1, ...item); } }); } else { return arr; } } }1
u/ShortSynapse Mar 05 '19
Why is Infinity too clever? And how is mutating the array in place within a
while(true)better?You should use the native Array#flat method. Pass it the depth that you want to recurse to. Whether that's Infinity to flatten everything, Number.MAX_VALUE for the same thing but using an actual number, or an arbitrary depth if desirable.
1
0
30
u/anselal Mar 02 '19
Try this one https://github.com/30-seconds/30-seconds-of-code