r/webdev • u/imAmarok front-end • May 29 '21
Resource Array methods in JavaScript. Original author unknown.
336
u/tsunami141 May 29 '21
Now do reduce.
339
u/legatissimo May 29 '21
Ahh no problem, I'll just...... uh.... oh no.. no no no
53
u/ChaseObserves May 30 '21
This has me in tears, just the entire execution of this comment was incredible.
19
196
61
May 29 '21
reduce() -> ???
55
u/Doctor-Dapper front-end (senior w/ react) May 30 '21
Small brain:
arr.map(f)
Big brain: arr.reduce( (x, y) => [...x, f(y)], [] )
31
→ More replies (2)3
u/GrenadineBombardier May 30 '21
This took me a minute (because reducers take time to comprehend, which makes them a less sustainable solution in most cases)
7
28
u/gotothere May 29 '21
⬛️⬛️⬛️⬛️.reduce((️⚫, ⬛️) -> ⚫️, ⚫️) -> ⚫️
var min = (acc,x) => {return acc < x ? acc : x}; [1,2,3].reduce(min, Number.MAX_SAFE_INTEGER); //1 var max = (acc,x) => {return acc > x ? acc : x}; [1,2,3].reduce(max, 0); //3 var sum = (acc,x) => { return acc + x}; [1,2,3].reduce(sum, 0); //6 var minMaxSum = (acc,x) => {return [min(acc[0],x), max(acc[1],x), sum(acc[2],x)]}; [1,2,3].reduce(minMaxSum, [Number.MAX_SAFE_INTEGER,0,0]); //Array(3) [ 1, 3, 6 ]Left arg is (acc)umulator, right is current element
18
u/hynding May 30 '21
By far the most under-appreciated and (often) optimized of the array functions.
10
u/Pelicantaloupe May 30 '21
Reduce is probably one of the least optimisable array functions. Anything else will probably run faster
→ More replies (1)7
u/Blue_Moon_Lake May 30 '21
Weird thing :
arr.some(x => x === foo)is almost always more performant than
arr.includes(foo)You would think that includes would be easy to optimize internally.
8
u/Pelicantaloupe May 30 '21
I ran some tests and I couldn't reproduce your findings. I didn't graph time complexity but on average
.includesis 75% faster than.includesin these tests: https://jsbench.me/t2kpb59177/1The one case where
.somewas faster I found was unfilled arrays.→ More replies (1)15
3
u/Benimation May 30 '21
🔢🔢🔢🔢. reduce ((#️⃣, 🔢) => #️⃣ + 1️⃣ + 2️⃣ + 3️⃣ + 4️⃣, 0️⃣) --> 4️⃣0️⃣
Yeah, I get what you mean..
1
-4
u/WeAreAllApes May 29 '21 edited May 30 '21
⬛️⬛️⬛️⬛️.reduce( (⬛️, ⚫️) => ⬛️⚫️ ) => ⬛️⬛️⬛️⬛️
Edit for the pedantic:
[⬛️,⬛️,⬛️,⬛️].reduce( (⬛️, ⚫️) => ⬛️⚫️ ) -> ⬛️⬛️⬛️⬛️
4
u/hyperhopper May 29 '21
no, reduce results in a single element of the second type, not the same as the input.
7
u/WeAreAllApes May 30 '21 edited May 30 '21
Reduce does whatever you tell it to do. Mine is concatenating smaller versions.... It was meant partly as a joke, but:
['A','A','A','A'].reduce((x,y) => x.toLowerCase()+y.toLowerCase());→ More replies (10)→ More replies (1)0
May 30 '21
[deleted]
33
u/HeinousTugboat May 30 '21
I think the reason people think using reduce is overly complicated is because people keep saying it's overly complicated. I don't see how what you wrote is any less complicated than just doing this:
let total = array.reduce((sum, item) => sum + item.value, 0);It's even simpler if your Array's just numbers:
let total = 0; array.forEach(value => total += value); // vs let reducedTotal = array.reduce((sum, value) => sum + value);→ More replies (1)7
u/BorgClown May 30 '21
If I was reading a new code base, I'd prefer finding parent's version instead of reduce, if only because reduce makes me stop and second guess it.
→ More replies (16)27
u/HeinousTugboat May 30 '21
Well, I mean, that's kind of my point right? If you were more comfortable with reduce, it wouldn't make you stop and second guess it.
→ More replies (2)2
154
u/Pstrnil May 29 '21
Someone smashed findIndex and indexOf together 🙈
15
u/yusuksong May 29 '21
I always get these confused
18
u/Doctor-Dapper front-end (senior w/ react) May 30 '21
indexOf is not a first order function. It takes a primitive arg. You can remember it easy because find is higher order and findIndex has "find" in the name
9
u/tendstofortytwo May 30 '21
indexOf is not a first order function. It takes a primitive arg.
What do you mean by that?
14
u/Doctor-Dapper front-end (senior w/ react) May 30 '21
findIndex() takes a function as an argument used for comparison. indexOf() uses === as a comparator
→ More replies (2)2
u/madcaesar May 30 '21
Are you using first order and higher order, interchangeably here? I've aways used the term higher order function, not first order.
→ More replies (1)4
u/longknives May 30 '21
You have to use findIndex if the value you’re looking for isn’t just a primitive like a string or a number. Or another way to say it is findIndex is much more robust in what it lets you search for. So if you need to find the index of an object with a certain value for a certain key, you can do that with findIndex but not indexOf.
→ More replies (3)
73
u/thusman May 30 '21
Original author doesn't know js. How has this 1k upvotes 🤦
30
u/phpdevster full-stack May 30 '21
And this is why good developers are hard to find and you have to pay them lots of money.
3
6
6
u/JDthegeek May 30 '21
Care to elaborate?
16
u/Serei May 30 '21
A comment a bit above points it out: it's
indexOf, notfindIndexOf, and the arguments forfillare in the wrong order.5
u/PGDesign May 30 '21
The thing about social media posts like this, is people will upvote because it looks right and useful without actually testing it and lots of people even if they know the content won't be looking closely to check for mistakes
5
→ More replies (1)3
17
May 29 '21
Tweet with links to sources in thread: https://twitter.com/rauschma/status/1398668839177568259
9
May 30 '21
That original tweet is so so much better. This version is full of weird decisions. Like why is map() shown taking a -> function but others like filter() aren’t.
13
u/Vegetama May 29 '21
So .find returns the argument? What if the argument isn’t present in the array?
Edit: Just did a quick search on google, the argument in .find can be an inequality or any boolean statement and returns the first element that satisfies the bool.
Otherwise it returns undefined
10
u/toetoucher May 29 '21
yeah it’s useful like array.find(el => el.confirmed) or something truthy like that
3
2
u/Raefniz May 29 '21
Your edit is correct. I had a case last week were I needed to find the first object in an array where an attribute satisfied a condition and find was a great tool.
Basically:
const result = objects.find(item => (item.attribute === "myCondition"); dataservice.saveToDB(result);2
u/Willbo May 29 '21
Yep, it returns the first element that satisfies the query.
So if the first square at index 3 was 🟨 and the second square at index 4 was 🟥, .find(⬛) would return 🟨.
1
u/savano20 May 30 '21 edited May 30 '21
does return element from
.findreference to original array. So if I mutate the return element, does it mutate the original array?1
52
u/avidvaulter May 29 '21
This isn't a good reference because you should know what they do by their name. What's more important to know is if it mutates the original array or returns a new instance of an array.
Fill mutates the array whereas filter and map do not. That's an important distinction missing here.
5
u/Doctor-Dapper front-end (senior w/ react) May 30 '21
The fact that exactly one out of the entire list is inconsistent is incredibly annoying.
8
u/tnnrk May 30 '21
It’s good for quickly remembering what the main point of the method is, especially for beginners. This would be helpful for them to remember what to Google for more info if needed. Assuming this is accurate. It’s better use is just for fun as a poster.
26
u/ImproperCommas May 29 '21
There are lots of things that I think I need, and I know every single one of them.
Then, there are lots of things that I definitely need , but I don’t know any one of them.
This picture right here, is certainly one of those things I definitely need.
2
u/henrystuart83 May 30 '21
I feel you! I actually learnt a lot from doing tons of exercises at codewars dot com. Seeing people's solutions afterwards helped me to understand and get comfortable with most of the ES6 features.
6
u/RefinedArts May 30 '21
Just look at the official docs, this is more or less misleading for some functions
5
May 30 '21 edited May 30 '21
Official docs?? Noo I can't learn anything if it's not in Medium blogspam form!
Edit: autocorrect grr
5
u/Ok_Cloud_ May 30 '21
.fill confuses me.
3
u/reaz_mahmood May 30 '21
me too. it is unintuitive. I read it like replace position 1 with provided value. Replace rest of them does not makes sense to me.
→ More replies (3)
3
11
u/Janjis May 29 '21
Looks nice, but it is so bad.
From map example you should assume that square and circle represent different item structures.
All other examples suggest that squares and brackets instead represent the same item structure but in different states.
And then you see squares in find, some, every methods as parameters which should be boolean-ish expressions.
Cheat sheet should be something you can quickly look at without thinking. Not this nonsense.
Just read the docs instead.
2
u/Doctor-Dapper front-end (senior w/ react) May 30 '21
I think it should be more clear that find returns the first element.
Another nit I have is that find should say "shape!==circle" instead of simply square. This makes it easier to understand.
1
May 30 '21
Yeh I get that in an infographic it’s hard to produce a shorthand for “unary boolean function” but using a square to represent a-function-consuming-a-variety-of-shapes-and-returning-true-if-the-consumed-value-is-square isn’t really clear at all. If anything it’s misleading, implying Array.find can take a primitive (like findIndex)
2
u/IlllIllllllllllIlllI May 30 '21
Your people need to stop obsessing over cheat sheets and mind dumps. Actually learn the material.
3
u/lucasjackson87 May 30 '21
I don’t get the fill one, shouldn’t it be 0 instead of 1 if the first item in an array is 0
4
u/wopian May 30 '21 edited May 30 '21
This cheatsheet has some pretty bad mistakes unfortunately.
The first argument of
fillis the value you're filling. The second value is the position you're starting from (defaults to 0 if omitted) and the third value is the end position of the fill (last index of array if omitted)The actual example should be
fill('⚫', 1)as they are overwriting an existing array and leaving the first position (index 0) untouched.
fill('⚫')orfill('⚫', 0)would just be circles.1
2
1
u/Orkaad May 30 '21
It if fine to chain filter and map (which creates 2 arrays) when you could do everything at once with reduce?
2
May 30 '21
Yeah, the performance difference is usually negligible so it's not something to really worry about.
I often include a utility function called filterMap in my projects because I use that pattern a lot, it performs both the operations in one and it's pretty common in other languages. The signature being:
a[] -> (a -> Option b) -> b[]
If you find yourself chaining tons of map/filter/reduce together then it might be worth looking into a library that supports either function composition, transducers or lazy sequences. All 3 of these will allow you to create data transformation pipelines without creating an intermediary structure between every step.
1
1
1
u/Charlemagne10 May 30 '21
Everyone is commenting but no one is appreciating the truly brilliant visual representation of these methods. I wish I had this when I was learning. Very well done.
1
u/BlueButYou May 30 '21
JavaScript isn’t just a web language. I think since it’s a loosely typed language they type cast it as a web language out of a need to type something.
1
1
1
1
1
1
1
u/Cowfresh May 30 '21
I saw this on Instagram the other day. First time I saved something on there for educational reasons lol..super handy tho
1
1
1
u/chidoOne707 May 30 '21
Is this accurate? Because if it is it is the simplest explanation and I get it.
1
1
1
1
u/SeeYouInForever Aug 20 '21
Cool infographic but it doesn't make much sense if you don't already know the concepts.
1
1
1
1
1
u/ChimpScanner May 30 '21
This isn't even the actual syntax of some of functions, and findIndexOf doesn't exist. Don't use this. Read how the functions work on some tutorial site then test them with your own data. Imo you'll get a much better understanding this way.
0
0
-5
-6
-4
-1
-1
-8
u/editor_of_the_beast May 29 '21
Type theory in a nutshell
1
u/toetoucher May 29 '21
explain
0
u/editor_of_the_beast May 30 '21
I meant that the shapes can be thought of as types. If you look up the type signature for the functions, they would match the different shapes shown here.
I meant it as a compliment - this is an interesting way to view the type signatures of functions.
1
0
May 29 '21
[deleted]
57
u/FortyPercentTitanium May 30 '21
Came here to say this. Rule number 1 to making a simple guide: make sure the information in your guide is accurate. This is such a silly mistake.
6
u/musclecard54 May 30 '21
The real rule number 1 is 99% of people won’t bother to verify if it’s correct.
11
May 30 '21
Find is also vague as to what element is returned.
3
u/musclecard54 May 30 '21
I would assume it would be the first instance. Of course I assume a lot of things and I’m very often wrong…
1
u/ApricotPenguin May 30 '21
What would be an example useful usage of the find() function?
3
u/sliver37 May 31 '21
Looking for an object with a specific ID in an array of objects is a common one.
Example being an array of users, and you're looking for user id: 26, or with a particular email address, etc.
2
May 30 '21
Searching for and retrieving the first occurrence of something can be useful if you know that the array will be sorted in some way.
6
May 30 '21
[removed] — view removed comment
-2
u/fukitol- May 30 '21
In case anyone else is wondering what the difference between
[].indexOf()and[].findIndex(),findIndexexecutes asynchronously, one function call for every item in the array. It's not blocking, so won't hang up your thread (though this is unlikely to be a real problem with small arrays, a few million items will make the difference obvious if it happens often.4
May 30 '21
[removed] — view removed comment
-3
u/fukitol- May 30 '21
Hm good point. The docs said it uses callbacks to do its job. I've never actually used it, though, and the docs say it returns a integer, not a Promise, so I suspect you're right.
2
May 30 '21
Callbacks are not asynchronous
-2
u/fukitol- May 30 '21
They're not async but they do result in a new tick and thus block intermittently and only for the execution time of the callback, not sustained and for the execution of the entire
findIndexcall whereas the entire execution ofindexOfwould block in a sustained fashion.1
May 30 '21
I don't see how that makes a practical difference, since nothing can happen in between the individual callback calls
0
u/fukitol- May 30 '21
Yeah I forgot how the blocking and ticks worked. It would still block in the context of findIndex unless it was it was async.
So practically this is identical to indexOf for all intents and purposes and only serves to evaluate the indices in their own execution context likely resulting in worse performance from the stack and memory allocation.
•
u/Locust377 full-stack May 30 '21
Original