Is reduce() bad? - HTTP 203

  Рет қаралды 78,149

Chrome for Developers

Chrome for Developers

Күн бұрын

Пікірлер: 320
@dasten123
@dasten123 4 жыл бұрын
So I should REDUCE the usage of reduce
@dassurma
@dassurma 4 жыл бұрын
Eyooo
@dev_time
@dev_time Жыл бұрын
Recursive reduction?🧐
@Textras
@Textras 4 жыл бұрын
Reducing complexity with cleaner code results in faster development time for all. The idea of better code readability is highly underrated and the more advanced our developer is, the easier it is for anyone to read and understand the purpose of it.
@Benimation
@Benimation 4 жыл бұрын
This is not the video title you want to see after having used it twice today..
@diegovideco
@diegovideco 4 жыл бұрын
If readability === communication of intent, then I'd rate as follows (filter >= map > reduce > for loops): 1. filter: may only shorten array 2. map: will only convert array elements from one type to another 3. reduce: will only return value of the type of the accumulator 4. for loops: may do any or all of the above plus then some (need to read function in full to understand intent) For loops may mutate one value, but they may mutate more than one, plus have side-effects, so one never knows. For reduce one only needs to look at the accumulator to see what's the result (if the actual type of the accumulator is not immediately obvious please document). Loops outside of functions are even worse than complex reduce outside of functions, because they often need to create variables outside their scope. It's true that reduce invites this precisely because it does not need to create unnecessary variables. But anyways it's an unfair criticism. In the end if people in the team don't want to learn reduce (not that hard, really), therefore not being to express or communicate intent with it, then that's a better reason not to use it than "readability" as an abstract universal thing.
@RyanTosh
@RyanTosh 4 жыл бұрын
The only use case for reduce() I've found is getting the sum/average of an array. Also, couldn't reduce still return a different type? Say, [].reduce((acc, el) => "hi", 4);
@diegovideco
@diegovideco 4 жыл бұрын
​@@RyanTosh well, in JS you can sure do all sorts of unintended stuff because of the lack of a type system. That's why I put an emphasis on _intent_ and communication. Try doing that in a strongly typed language and the compiler will complain. What I mean is, as rule to use and understand reduce, if you intend your function to return a string then put a string in the initial value of the accumulator, and so on with any other type. In JS this responsibility is laid on the programmer, but the discipline it requires is good and helpful.
@diegovideco
@diegovideco 4 жыл бұрын
As far as uses go, there's a lot. Basically anything that may need to accumulate a value. They are kind of the functional and more declarative substitute to loops (because the accumulator states the type, and de discipline), and an alternative to recursion. Many higher-order functions can be implemented with reduce, including map and filter. But also very useful things that JS still lacks, like groupBy, partition, or pipe. Get to know and give yourself the opportunity to use it and you'll find many more, and you'll see if you enjoy it or not. It's really not bad in itself. Also read about fp in JS, there's a lot of good free stuff around. Once again, no one is saying you can't do all that with loops, but the whole reduce is bad meme/dogma makes it look much harder than it is (it's as hard as learning loops in the first place, just from a different point of view... some people don't like change or go beyond what they are used to, or going back to square one, but it does not mean it more complex). Kind of shuts off the possibilities of the language (and prevents people from more easily venturing into other functional languages that can be very interesting and joyful, like clojure/script, elm, haskell, etc).
@welltypedwitch
@welltypedwitch 4 жыл бұрын
@@diegovideco I 100% agree with you :)
@benjaminbenson2817
@benjaminbenson2817 4 жыл бұрын
Perhaps I'd add the array function "sum". like some >= filter >= map > reduce > for loops
@ghostinplainsight4803
@ghostinplainsight4803 4 жыл бұрын
I use reduce anytime I need to make an array of things into a single thing, that's it's purpose and it communicates it better than a loop communicates it's purpose because a loop is too abstract and I need to read the code inside and often outside to understand what it is doing. I just read a single function for reduce and I can understand what it is doing. The code you showed was overcomplicated.
@halfalligator6518
@halfalligator6518 3 жыл бұрын
totally depends what you're reducing and how you're doing it. The point is that reduce is often not helping at all.
@Kaldrax
@Kaldrax 4 жыл бұрын
My main usage for .reduce() is the combination of .filter() and .map() because it only iterates once over the array and in contrast to using a loop you don’t have to define the output variable first.
@malydok
@malydok 2 жыл бұрын
Did you try .flatMap()? Might fit your use case.
@antifa_communist
@antifa_communist Жыл бұрын
What do you mean output variable?
@dibaliba
@dibaliba 4 жыл бұрын
Yes, I did read. I am a fan of reduce, but I only use it to do simple things. Extracting the callback become a function with name is also a game-changer, make code more expressive.
@ilovecomputers
@ilovecomputers 4 жыл бұрын
>"Don't use reduce, it's hard to understand and show off-y" >suggests using iterators
@cat-.-
@cat-.- 4 жыл бұрын
Lol he's not telliing you to use iterators. He's got iterators all confined in his well-named functions!
@mishasawangwan6652
@mishasawangwan6652 3 жыл бұрын
uh yeah. 100%.
@justafreak15able
@justafreak15able 3 жыл бұрын
atleast 60% of developers can understand what filter and maps are.
@clickrush
@clickrush 4 жыл бұрын
I agree with the sentiment that reduce can typically be mis-/overused since it is so close to a generic loop. It is also very easy to accidentally re-implement more specific higher-order functions such as filter/map/flatMap/find/every and so on, because reduce is so generic. But one important aspect which was largely left out in this discussion is that both reduce and(!) a reducer are functions and thus closures. They can be composed, be part of a composition, be passed from another place to capture a frame, they can be called within other contexts and so on. Yes you could wrap a loop into a function to achieve similar things but then you would just re-implement reduce. Yes, when thinking of using reduce and writing a reducer one should very likely look for an alternative first, usually composing more specific functions is the way to go. But by writing specific for loops one almost always loses the opportunity for a declarative approach and possible abstractions. On a more general note I disagree with the idea that code should always look as simple as possible (as proposed in the video). In the first draft or exploratory phase I would recommend it, but sufficiently abstracted functional code can often easily lead to separating concretions (AKA data), which enables code-reuse and testability. So when given the opportunity and seeing a possible gain one should consider this. Data Driven code with generic functions is often much more declarative and easy to understand than 'simple' code if carefully written.
@Isti115
@Isti115 4 жыл бұрын
Finally, someone with a higher level view, not just looking at the direct readability gain, but also the potential further advantages, which in my opinion far outweigh the negative aspects, and also, I think that there's a valid reasoning behind getting people smarter, so they won't have trouble reading more abstract code.
@Slashx92
@Slashx92 2 жыл бұрын
"Yes you could wrap a loop into a function to achieve similar things but then you would just re-implement reduce". Or implement a function that only creates one result variable and mutates it. Even with that statement reduce can easily be overruled by a simpler and better ad-hoc function.
@andreasherd913
@andreasherd913 10 ай бұрын
what you describe are basically transducers. they implement map/filter and other things as a reducing function. composable, re-usable and skips intermediate allocations. It's always sad to see people arguing that stuff they don't understand or they find hard to read is bad. We are in this to learn things not diss them.
@MichaelBckerLarsen
@MichaelBckerLarsen 4 жыл бұрын
Episode should've been called: "Turn it into a loop"
@beyondant
@beyondant 4 жыл бұрын
19:51 I guess the simplier way is to just use edges.filter(v => v && v.isSeen).length;
@ChazAllenUK
@ChazAllenUK 3 жыл бұрын
Unless you work at Google... then it's a loop!!
@Buslowicz
@Buslowicz 4 жыл бұрын
Surma: you can make it a map, wrap it in a function, or write a loop Jake: WRITE A LOOP!!!!!!!!
@frameshifty
@frameshifty 4 жыл бұрын
This should be renamed to "Is bad code bad?" The examples used as arguments against reduce are obtusely clever and clearly should be broken down into easier to read code.
@sney2002
@sney2002 4 жыл бұрын
flattening an array before .flat() existed function flat(array) { return [].concat.apply([], array); }
@Jespertheend2
@Jespertheend2 4 жыл бұрын
Jhonatan Sneider Salguero Villa their example also shows the spread operator. Didn’t flat exist before the spread operator?
@sney2002
@sney2002 4 жыл бұрын
​@@Jespertheend2 according to caniuse flat was added after the spread operator spread operator = chrome 49, firefox 34 .flat() = chrome 69, firefox 62
@ColinRichardson
@ColinRichardson 4 жыл бұрын
would Array.prototype.concat be more appropriate for that? So you don't make an additional array??
@sney2002
@sney2002 4 жыл бұрын
@@ColinRichardson Yep, that would be better.
@SargsyanTigran
@SargsyanTigran 4 жыл бұрын
"Reduce is bad." Surma: "wrap it in a function and hide it out of my sight!" 🙈
@isfland
@isfland 4 жыл бұрын
We can write smart code. Pure code. Most performant code. But I like that your north star is readable code and you prefer the most readable option among all examples.
@rlamacraft
@rlamacraft 4 жыл бұрын
I like the format of finding code in the real world and suggesting improvements (Paul’s original supercharged was always very entertaining) However, I think the conclusion that reduce is bad is completely off. I could come up with “clever” unreadable loops just as easily as I can with reduce. Really the conclusion should be: *abstract units of computation into small functions* and let the tooling optimise the code shipped to users. This isn’t always the case (chaining map and filter is obviously better than reduce), but even then I would abstract them out to their own function.
@dassurma
@dassurma 4 жыл бұрын
Are you saying that the title is clickbait??! No wait, I said that at the start of the video ^^
@leonk6950
@leonk6950 4 жыл бұрын
One use for reduce is when actually working with *reducers*. When you’re doing a lot of list-processing, using reducers is a great way to help readability. (A reducer is any function that could be given to reduce, I.e. sum (+), max, min, etc. creating custom reducers for your data processing pipelines can be really helpful, especially when working with dynamic stuff (say the user can choose if he wants to see min, max or total of a list of numbers. Instead of calling different functions, you can just have one variable „selectedReducer“ and put that into array.reduce, reducing complexity a lot and also making your code more expressive, as you’ve now put the users selection into a variable which directly matches his intent and is directly used as such
@MaxArt2501
@MaxArt2501 4 жыл бұрын
I mostly use .reduce for object building, partitioning and grouping (other than summing things together). As JavaScript evolved, the legitimate use cases for .reduce has been... reduced. But I still need to use it if my target environment would need a polyfill that I'm not allowed to provide.
@YuFanLou
@YuFanLou 4 жыл бұрын
MaxArt Reduce is the most generic recursion form there is. It has the same power as for loop. It is good practice that functions closer to the use cases are built on top of it and replace it in usage, just like how you write a function to contain a for loop. I just wish they stop treating it like it’s inferior just because they are not as familiar with it. Reduce is the same age as for loop. It was invented as fold in Lisp in the 1950s, along with for loop in ALGOL.
@elCoronelCC
@elCoronelCC 4 жыл бұрын
23:12 I assume the code can be simplified: data.notifications.edges .filter(v => v && v.isSeen) .length Code in the video: data.notifications.edges .map(v => v && v.isSeen) .filter(Boolean) .length
@abubakr380
@abubakr380 3 жыл бұрын
Actually .filter(Boolean) removes undefined and null values in the array
@SantoLucasST
@SantoLucasST 3 жыл бұрын
@@abubakr380 the first filter is already filtering the null and undefined, right?
@abubakr380
@abubakr380 3 жыл бұрын
​@@SantoLucasST Yes it does remove null and undefined values. However the filter function will return an array of "edges", while the map function will return an array of booleans. Therefore, the two approaches serve completely different purposes.
@kyzanhyuri5356
@kyzanhyuri5356 4 жыл бұрын
8:29 This was the point that made me decide to reduce my use of reduce. I didn't really think about it but it is bizarre to have the parameter at the end of the logic. Which you then would have to run through the sequence of logic again with the new knowledge of what's being fed first. It just breaks flow state. It is far smoother to have the parameters defined first and then read the loop logic.
@diegovideco
@diegovideco 4 жыл бұрын
here's why it can be a good idea to have data come last kzbin.info/www/bejne/o2TWp36Fmb-coKM&app=desktop Also it is a more or less standard order for reduce functions across many different languages
@mo3ath12
@mo3ath12 4 жыл бұрын
var arr =[1,5,6,4,5,95,5,5,]; Let sum = arr.reduce((s=0,t)=>s+t); You can utilize default value for the first argument , now it makes a lot of sense
@MarioAndreschak
@MarioAndreschak 4 жыл бұрын
The fact that you answered the question straight away and instead of beating around the bush for 14 minutes made me like and subscribe.
@ChazAllenUK
@ChazAllenUK 3 жыл бұрын
Is reduce() bad? - maybe Is making *everything* a loop bad? - yes *lodash* provides clean solutions to lots of reduce-like problems: keyBy, mapValues, invert, mergeWith, ...
@BudgieMind
@BudgieMind Жыл бұрын
It's amazing how, just in time, this video popped up in front of my eyes. I was writing a reduce function that was returning a map and literally used a snippet g = new Map from the video
@magne6049
@magne6049 3 жыл бұрын
18:33 For a slight win in readability, don't use `.filter(Boolean)`: // If you have an array with potential null values: const array = [1, 2, null, 3] // Don't do: array.filter(Boolean) // since: "wtf, it's an array of integers, not booleans?!" // Do: const isNonEmpty = f => f // you can define it once and for all somewhere else array.filter(isNonEmpty) Make it read out loud and clear. Don't make the reader have to think. Also, with respects to "That's a fun trick": Tricks are a code smell.
@rishabh_gour
@rishabh_gour 4 жыл бұрын
I don't always use reduce(), but when I do, I do that to look smart :)
@LasanaMurray
@LasanaMurray 2 жыл бұрын
Use reduce() to reduce a list of values into a single value, it's that simple.
@wdnspoon
@wdnspoon Жыл бұрын
On TypeScript, reducing into a Map has an advantage over the loop in that you can build a mutable Map, and return a ReadonlyMap.
@LuLeBe
@LuLeBe 2 жыл бұрын
Oh wow I used it at times to build strings. Basically the sum-like thing, maybe to put together all the option tags in a select based on an array and also have a default option (which is defined in the initial value). Could also be done with loops. I think reduce is not terribly hard to read for these cases though, where you basically just add the current array value (maybe with some transformation first) to the sum of the previous values. Certainly easier to understand for non-JS devs than stuff like spread operators etc.
@welltypedwitch
@welltypedwitch 4 жыл бұрын
I personally use reduce in the way that you would use foldl in Haskell (foldl is the same as reduce). I basically use it as an easier way to do tail recursion, when explicit recursion is too verbose (So the function should be rather short or some function you have already implemented). Example: foldl (+) 0 [1..5] Or in Js: reduce ((x, y) => x + y, [1, 2, 3, 4, 5]) With explicit recursion this would be: let f [] = 0 f (x:xs) = x + f xs in f [1..5] Or in JS: const f = (ar) => { if(ar.length === 0) return [] const [x, ...xs] = ar return x + f(xs) } f([1,2,3,4.5]) Btw. The reason the callback comes first is, because in an implicitly curried language like haskell you can just omit the array in a point free style :) So my main Point is that you find loops easier to read than reduce, because you're not used to that kind of recursion, but someone coming from a language like Haskell (like me) may actually find the reduce function much cleaner and easier to read.
@TheAxeForgetsTheTreeRemembers
@TheAxeForgetsTheTreeRemembers 4 жыл бұрын
Yes, but the problem is what you are using the language for. In their case it's for web apps, where people are not used to math or functional programming. The most important thing is to keep consistent with the context you are writing code in. (I believe) Interesting explanation for the order of the arguments btw.
@welltypedwitch
@welltypedwitch 4 жыл бұрын
@@TheAxeForgetsTheTreeRemembers Sure, but (at least in my opinion), programming for web apps is such a big field, that you should not limit it to one style of programming (especially if that style is known to be quite error prone). Also JS/TS is not only used on the frontend, but also in node (which is where I use it). Still, I totally agree with you about keeping the code simple and consistent (especially if it's open source) :)
@tomtrask_YT
@tomtrask_YT 4 жыл бұрын
Around 19:30. That conversion to Boolean in a filter does not filter out empty objects. An empty object is still truthy. It would filter out zeroes (numbers) and empty strings but supposedly those would break that node.isSeen test because strings and Numbers do not have a node property. A notification that lacked the node property would also break that example whether it was empty or not. The filter saved nothing. The rewritten code suffers from this same defect.
@andreo4511
@andreo4511 4 жыл бұрын
If you're just using reduce to keep the function pure there are other ways to do this. The most important characteristic of a pure function is that it's 'referentially transparent'. That means that you should be able to replace a function with its return value and have everything still behave the same. So you could replace reduce with forEach and just wrap it in a function so it doesn't mutate anything outside the function However if you may still need reduce if you want your code to be very concise or you need to chain functions
@myFBisXapu
@myFBisXapu 4 жыл бұрын
Almost every day part of my job is to aggregate data from various places and then show it somewhere over a web page (I assume this is the case for most FE developers) and so far `reduce` is one of my favorite tools for the task. In my opinion, when you understand how `reduce` works and if used on a daily basis, the snippets of code including `reduce` become quite readable and reasonable. Another thing that i like when using `reduce` (and chaining methods over iterable stuff) is the avoidance of mutations, which can be quite a painful problem when using series of loops to aggregate a set of data. Of course the extrems are bad and instead of ``` [].filter(Boolean) .reduce((count, { node })) => (node.isSeen ? count : count + 1, 0) ``` I will use some build-in methods like ``` [].map(v => v && v.isSeen).every(Boolean) ``` I'm fully aware that if you separate your code in small functions, that use loops and imperative style internally the returned result will be the same (in some cases it might be even more optimized) as if using more functional approach, (assuming that the inner works of the function work fine and there are no leaky parts :D ), but still, I think that reduce has its advantages in a lot of cases and sometimes saves a lot of writing time.
@konstantinkh
@konstantinkh 4 жыл бұрын
Reduce exists because it's a good paradigm in parallel computation. I know how to take a block of code using reduce that's taking too long and split it into tasks that won't without having to figure out what it was that you were trying to do. If you keep writing custom code for each of these, then you might as well just start from scratch any time you have to optimize anything. I understand that multithreading is a dirty concept to a lot of JS devs, but if you want time-to-interactive not to start skyrocketing now that we've hit the limit of what a single thread can do, you're basically going to have to learn to deal with it. And you might as well be getting used to map/reduce paradigms now.
@jakearchibald
@jakearchibald 4 жыл бұрын
Reduce doesn't work in parallel in JavaScript. But how would it work in parallel anywhere? Each function call depends on the result of the last
@konstantinkh
@konstantinkh 4 жыл бұрын
@@jakearchibald You generally need additional constraints. The simplest constraint is if b.reduce(F, a.reduce(F, z)) === a.concat(b).reduce(F, z) for given choice of F, z and suitable split of desired array into partitions a and b. Accumulation of a sum from zero is a trivial example. A more sophisticated example would be something like standard deviation computation, where the above constraint doesn't hold, but can be modified by keeping track of partition sizes to be true. Situations where the result truly depends on the specific sequence of inputs are rare in practice, and almost entirely limited to cryptography and hashing. A reduce problem can frequently be partitioned in a sensible way. Unlike map, you don't just let the machine handle this, of course. The algorithm has to be designed with a particular partitioning strategy in mind. But that's precisely why use of map and reduce as keywords are useful even compared to forEach. They signal the intent. I know that I can just split maps across cores without even thinking about it. I know that I'll have to take greater care with reduce, but I also know which patterns to look for in these to satisfy possible constraints. If I see a loop that does a bit of both, I know absolutely nothing without digesting the entire algorithm and probably re-implementing it from scratch to allow for parallelism. And yes, there are definitely misuses of reduce out there. And so many calls to reduce should really be calls to .map(...).reduce. But that's hardly a problem with the reduce itself.
@patfix
@patfix 4 жыл бұрын
Thanks Lucas!
@dwighthouse
@dwighthouse 4 жыл бұрын
Basically the only time I use Reduce is when I want to "filter" an object. fromEntries() is not supported everywhere yet and it requires creating a ton of tiny, intermediate arrays. But I agree with the sentiment of writing immediately clear code. That's why I recommend never using classical inheritance or any other mechanism that involves the possibility of spooky execution at a distance (proxies, getters, setters). Instead, use normal data structs and pure functions (or mostly pure functions) to operate on that data. If structural control/security is required, it can be added at the item level or the api level with closures or (now) module boundaries.
@jakearchibald
@jakearchibald 4 жыл бұрын
Using it to reduce objects is one of the worst cases of reduce. You're either passing the same object around in a loop (meaning you're only using the looping mechanism of reduce), or creating a new object each time which is really slow. Loops are faster and IMO are easier to read.
@dwighthouse
@dwighthouse 4 жыл бұрын
@@jakearchibald You're probably right. I'm still getting off the escalator of everyone telling me "Use map! Use filter!", when loops were perfectly fine in the first place. Change takes time. Still, if there were a nice way to filter Objects, this would have been avoided in the first place.
@mrhappy192
@mrhappy192 4 жыл бұрын
A good workaround for reduce's argument order is to just use one: array.reduce( (sum = 0, current) => current + sum )
@csorfab
@csorfab 4 жыл бұрын
This doesn't do what you think it does. The default value provided for sum will never get used. From MDN: "If no initialValue is supplied, the first element in the array will be used and skipped" developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce Try this: [1,1,1].reduce((sum = 5, current) => current + sum) The result, according to you, should be 8, but it is actually 3.
@lordfo99
@lordfo99 4 жыл бұрын
Just a hate talk, totally omitting any good code examples using reduce. I like some of your code rewrites, and agree with them, but the general message of this talk is bad. You just say, code simple, don't care about performance and scoping, just mutate, do side effects and create potential bugs.
@benjaminfrost1583
@benjaminfrost1583 4 жыл бұрын
They didn't say they didn't care about performance, just that it was secondary to readability in most instances. The cost/benefit tradeoff there is super situation specific.
@MishaAmashukeli
@MishaAmashukeli 4 жыл бұрын
Reduce is never faster than a for/foreach, so I don't know why you mention performance. The benefit of reduce over for loops is that it makes(should make) code simpler to understand, it can not give you a guarantee that the code inside is bug-free. When it actually makes the code harder to understand, then this code will be more error-prone and there is no reason to use reduce in such cases.
@marcusbrsp
@marcusbrsp 2 жыл бұрын
This video could have been reduced to three seconds, 1:29 - 1:32.
@JDalmasca
@JDalmasca 2 жыл бұрын
Credit to Jake for pointing out that the syntax for reduce() is terrible. The initial value goes at the end? No one thinks that way. I'm glad someone else sees that as problematic.
@api-first
@api-first 4 жыл бұрын
Is the function at 8:41 broken? In the comment for this function it stated that the function should return [1, 3, 6, 7] for an input of [1, 2, 3, 1] - but it returns [1, 2, 4, 7, 8]. It always just takes the last number in arr, adds to it the next input value, and concats it to the arr. In order to work as described in the comments if would need to sum all items prior to the next input value.
@csibesz07
@csibesz07 4 жыл бұрын
You are right, there is a bug and i'm really surprised they didn't catch it with their 20years of experience :), one solution: return input.slice(1).reduce(...) , the issue is reduce start at index 0, but we already counted it with [input[0]].
@davidtheprogrammer
@davidtheprogrammer 4 жыл бұрын
That code that's supposed to return a running total is incorrect. I ran it and the results don't match the expected result in the comment above. Also I was able to do it with a loop... Check below ``` function loopImplementation(input) { let currentTotal = input[0]; const finalArray = []; input.forEach((value, index) => { if(index == 0) { finalArray.push(currentTotal); } else { currentTotal += value; finalArray.push(currentTotal); } }); return finalArray; } ```
@mrusagi1004
@mrusagi1004 4 жыл бұрын
Yes, that confused me as well. Just to add something, a correct reduce implementation could look something like the following. But I guess at that point a loop implementation would be preferable. relativeToAbsolute(input) { return input.reduce( (arr, val) => { return arr.concat(arr.length > 0 ? arr[arr.length - 1] + val : val); }, [] ); }
@emilemil1
@emilemil1 4 жыл бұрын
Oh dear god that relativeToAbsolute. 1. It's incorrect. With the input given in the comment it produces [1,2,4,7,8]. Really goes to show how easy it is to botch things when using Array.reduce. 2. It doesn't have any advantage when it comes to speed compared to simpler solutions. 3. It's not quick to write or easy to read. This function using map has equal performance (on Chrome), is faster to write, and is easier to understand (+ it actually gives the correct result): function relativeToAbsolute(input) { let accumulated = 0; return input.map(val => accumulated += val); }
@Idolaughtmyheadoff
@Idolaughtmyheadoff 4 жыл бұрын
I use reduce mostly in cases where a need to create multiple arrays from single array by some criteria. For example in array of entities I need two arrays: removed and alive entities. It can be replaced with calling filter two times over this array, but reduce will be better because it iterates over array once.
@dassurma
@dassurma 4 жыл бұрын
As I say in the video, I think these are often unnecessary performance optimisations. Most of the time, arrays are not big enough to have a meaningful performance difference. I'd rather have expressive code. And even after all that, creating multiple arrays from one is a case for a loop, not a reduce() function.
@drissAithafid
@drissAithafid 4 жыл бұрын
TLDR: In most of the examples you used I agree with you if you're talking about small arrays. You're right that readability comes first over performance, but actually, if we're working with a huge array we should consider performance first. like for example, in the last example about images.thumbnail you're code is more readable but in case of huge arrays your code rewrite is less performant because you're iterating over the array of images twice (map() + filter() ), while the original one iterates just once using reduce().
@fateriddle14
@fateriddle14 4 жыл бұрын
I actually find while reduce doing reduce things(meaning turning an array into a string), they are quite readable, like arr.reduce((a,b) => a+b)
@tobyfried
@tobyfried 4 жыл бұрын
Agreed. The functional-style array methods really shine when used for quick one-liners.
@danilaplee
@danilaplee 4 жыл бұрын
reduce looks more readable for me than your loops, maps & function chains, which like you said require generators to be optimal in performance and async generators are any programmers worst nigthmares (and don't work in ts) :)
@jasonleelawlight
@jasonleelawlight 4 жыл бұрын
Personally I don' have problems with reduce() as long as the logic in the callback is very simple and easy to follow, and most of the examples in the video are not like this. In general if I see someone making up unnecessarily complicated stuff I would ask them why they are doing so and how they can simplify and refactor it, this will discourage those who just want to show off without any concerns of code quality.
@microcontrolledbot
@microcontrolledbot 4 жыл бұрын
So, your issue with reduce is the argument implementation due to the callback not being the last argument. Which I agree with, I've always hated specifying the accumulator as the final argument but reduce is amazing and I will not use it any less in favor of loops. It has it's place and I for one welcome it with a open heart and mind.
@cameronm256
@cameronm256 4 жыл бұрын
For a couple of these I noticed that haskell, a language designed for functional programming, has a function more suitable than reduce built in which would make the implementations a lot clearer: * For the `relativeToAbsolute` example, `scanl`: hackage.haskell.org/package/base-4.12.0.0/docs/Prelude.html#v:scanl * For the "jsx join" example, `intersperse`: hackage.haskell.org/package/base-4.12.0.0/docs/Data-List.html#v:intersperse Is the issue here just that JS lacks the tools for doing FP?
@jasonleo
@jasonleo 4 жыл бұрын
Editor Lucas is really cool!
@blipojones2114
@blipojones2114 4 жыл бұрын
Aside from actual code. The best use of reduce is to ask about it in code interviews, usually when we review a fake PR together. It's not a bad way of finding out how far along the "learning journey" a dev actually is, regardless of years experience. Are they just on it cause its trending? they even recognise it may be harder for others to read? So ye, it's handy for "reducing" a pool of candidates.
@lilkwarrior5561
@lilkwarrior5561 4 жыл бұрын
Many would find `forEach` far more "readable" than `for of`. Also, there's other values than readability why some might find `reduce` far better than `for of`-particularly some would want to avoid for whatever reason the added global variables that a for-of loop requires. Accordingly it's extreme I think to say devs are "abusing" reduce for things like the graph reduce example. The other elephant in the room is that there's a significant amount of JS developers that prefer the composable functional approach of applying transformations to looped code that reduce helps facilitate (transducers) that enhances readability subjectively for those people. Overall, i think Google should do less videos like this that's on subjective matters such as readability versus more quantitative things like performance.
@jakearchibald
@jakearchibald 4 жыл бұрын
for-of does not require global variables
@vladislavstepanov7591
@vladislavstepanov7591 4 жыл бұрын
In my opinion, readability is more important than perfomance cuz we usually work with small amount of data
@lilkwarrior5561
@lilkwarrior5561 4 жыл бұрын
Vladislav Stepanov I’m not weighing the importance of Readability vs performance. I’m saying it’s not objective and is a bad fit for this show that primarily is usually just Jake & Shurma who do amazing jobs on a variety of other topics. It’s an incredibly subjective topic that at least needed more representation of devs involved. Readability is very contextual that spans far more than the opinion of 2 programmers here who happen to be on the same page. You need to account how familiar a team is with certain topics, acknowledge your own bias as a programmer who has decided to use certain languages that come with built-in biases towards what you can do & not (impacting the rate you’re exposed to alt ways of doing the same things you’ve done); & so on… It’s quite telling the examples of this particular episode didn’t involve devs who have styles or have code bases they feel strongly about the use of reduce over loop; it’s common knowledge there’s meaningful amount of devs who do considering among the top libs in all of JS are functional & include what many find better versions of reduce for styles of programming a significant portion of JS devs find far more readable than loops (reactive functional programming comes immediately to mind)
@tjkandala5650
@tjkandala5650 4 жыл бұрын
Thanks for bringing up transducers. You really can get the best of both worlds (readability/composition and performance) with transducers. It becomes easier to understand and change each step of the process with transducers, which the main value proposition of using methods like reduce(). I wrote a pseudo-transducer (github.com/tjkandala/obsducer/blob/master/README.md#performance) which performed almost as well as for loops on huge arrays. My "transducer" is a hack built with RxJS (because I wanted to use RxJS operators more often lol. Glad you brought up reactive programming as well), but many people have written "proper" transducers a la Clojure with similar performance profiles. My transducer in practice (github.com/tjkandala/xplosive/blob/master/src/workoutGenerator/calculateIntensity.ts#L70). I didn't go through a CS degree so to me, for loops genuinely take more work. I prefer to offload as much "mental state" as possible to my computer (with TypeScript, simple abstractions) so I can commit my working memory to solving problems. reduce() helps me write code that would probably be really buggy if I wrote it the "easy way," by way of hiding implementation details.
@TheNewton
@TheNewton 4 жыл бұрын
"Google should do less videos like this that's on subjective matters such as readability versus more quantitative things like performance" ROFLLOLOLOLOL what? The depth of irony that statement is for. This like how Crockford got grief for encouraging readable code and linters to minimize bugs instead of doing stuff that makes compiler jocks happy, or people were just used to getting away with. Google's been one of the largest proponents on web performance, pushing a lot of the cultural standards in modern web development. So when their devs talk about readability being more important than performance that's a clue that readability influences and *scales* performance of software development on the web. A mistake made in this video and other such talks is treating readability as 100% subjective, when the problem is that we lack the tools and concepts to measure readability objectively as all modern trends have been towards speed metrics mostly AFTER the fact also because it's such a large problem that goes beyond soft-dev a problem mostly solved by having the ethos of readable code before worrying about performance. If you need an objective litmus test just put all your code through a minimizer, delete all your old unminimized code and from then on only codegolf in minified javascript and measure your error rates.
@magne6049
@magne6049 3 жыл бұрын
15:32 A for loop would still be much easier to read (and require less knowledge) than using Object.fromEntries, Object.entries, and map. See how clear it is, even when constructing an object: ``` const events = Object.keys(this.state.events) const handlers = {} for (const event in events) { handlers[event] = this.eventDidFire.bind(this, event) } ```
@DrRobrez
@DrRobrez 4 жыл бұрын
My most common usage of reduce is to create a dictionary of some sort from a list of objects.... I always struggle to write these vs a loop that does the same thing
@Luxalpa
@Luxalpa 4 жыл бұрын
use Object.fromEntries() and map()
@eboubaker3722
@eboubaker3722 4 жыл бұрын
Yes i read the video description
@BlackKillerGamer
@BlackKillerGamer 4 жыл бұрын
usually the problem is not the reduce; it's the function that is passed to it, as is with all other higher-order functions. just give it a name: list.reduce(sum) // instead of list.reduce((a, b) => a+b) list.filter(exists).reduce(join(', ')) // instead of list.filter(x => !!x).reduce((acc, x, i) => i !== 0 ? [...acc, ', ', x] : [x], []) // or whatever btw join would be implemented like const join = sep => (a, b, i) => the above... (though I'd prefer pairing everything with a comma and stripping the last one after, so you don't have to think like you're in a loop with an iterator / in a zip with a range) imo that way the code is rather close to natural language, as long as the function names are meaningful
@olimsaidov
@olimsaidov 4 жыл бұрын
The term "sequential code" is misused. The only reason why reduce doesn't look like "sequential code" it's because the callback function usually inlined. But you are free to separate it as a named function for readability. Small functions with small localized scope are better then large chunk of "sequential code" with common scope.
@jakearchibald
@jakearchibald 4 жыл бұрын
Putting the callback elsewhere makes the code less sequential. If you're going to make a callback anyway, put the whole operation in there and use a loop.
@I-M-Pulsive
@I-M-Pulsive 4 жыл бұрын
Why not use CSS for the map function where it wants to join the links with a comma?
@jackbennett2760
@jackbennett2760 4 жыл бұрын
I think this is right, your rewrite of flat only flattens 1 level of array? The reduce will flatten any number of nested arrays.
@tjerkannemeesters6238
@tjerkannemeesters6238 4 жыл бұрын
The relativeToAbsolute() function doesn't actually do what the code comment says; it returns [1, 2, 4, 7, 8]
@nialltracey2599
@nialltracey2599 4 жыл бұрын
I don't like the syntax of .reduce (or .map or .filter) but the concept is sound. I personally love Python's list comprehensions and generator expressions, because they offer a clear, concise depiction of the intended function (and before anyone says "custom for loops are more efficient", maybe so, but haven't you ever heard the expression "optimise late"?). .reduce's problem is that by being just another function with a general reliance on unwieldy unnamed functions, the syntax isn't clear, so isn't as expressive as the underlying idea is. I can't think of a way to make reduce visually expressive in plain text (or I'd have submitted an RFC to the Python maintainers ages ago!) but it does encapsulate a single logical idea into one thing. The alternative is trying to decode a much longer piece of code to work out a) what it's supposed to do and b) what it actually does.
@aokihu
@aokihu 4 жыл бұрын
REDUCE() is a powerful function, it can solve many problem with simple logic
@jakearchibald
@jakearchibald 4 жыл бұрын
You could say the same about loops
@aokihu
@aokihu 4 жыл бұрын
@@jakearchibald REDUCE is like loop, but it is very useful in functional programming
@jakearchibald
@jakearchibald 4 жыл бұрын
It's good for sums, but pretty difficult to read for everything else, compared to loops. For what it's worth, the creator of Python agrees www.artima.com/weblogs/viewpost.jsp?thread=98196
@lilkwarrior5561
@lilkwarrior5561 4 жыл бұрын
Jake Archibald The Python creator bit can easily be seen as an appeal to authority fallacy.
@MaximillianHeth
@MaximillianHeth 4 жыл бұрын
Is it that difficult to understand how reduce works though? In functional programming, reduce is extremely useful for functional composition in ways that would be far more convoluted to replicate with either map or filter.
@stannone7272
@stannone7272 3 жыл бұрын
I hope Surma, did not get sick too.
@JonAthan-ln2wn
@JonAthan-ln2wn 4 жыл бұрын
There is actually quite some reduction happening in Surmas underdash. 😬😄
@lilkwarrior5561
@lilkwarrior5561 4 жыл бұрын
Readability is such a subjective thing, especially when it comes to JS where a lot of styles are supported and what langs & edu you had throughout your programming years. It doesn't really matter how long you program (2 years, 50 years, whetever), if you haven't been exposed not at all to a different style of programming primarily devoid of what you've used over your experience, of course some things are considered far less readable to you. Let's say if someone's first language was Haskell and they primarily only used functional programming, they'll find some of these examples frustrating and less readable than the imperative code written. The values you pick up subjectively throughout your career you didn't have when you first program you learn greatly impacts your lens on readability. For example, IDK about the graph example being more readable than the reduce version; to me the reduce version was more readable and it was ANNOYING you had to create a global variable to generate the graph. That's nitpicking of course, but my point is that this video was often doing appeal to authority fallacies on why the reduce one was worse than the `for of` which is less readable to many simply because it's `for of` instead of another syntax some find more "readable" such as "forEach".
@jakearchibald
@jakearchibald 4 жыл бұрын
You keep saying global variables, but this isn't a requirement. You can create variables in block & module scope.
@lilkwarrior5561
@lilkwarrior5561 4 жыл бұрын
Jake Archibald That’s what I meant; sorry that was confusing about my related messages about this. That said, that’s undesired by some as unnecessary cognitive noise.
@KManAbout
@KManAbout 2 жыл бұрын
i mean sure if we lived in a world where most people's first language was haskell. it largely is not though. haskell is not very popular nor are any functional languages
@lilkwarrior5561
@lilkwarrior5561 2 жыл бұрын
@@KManAbout I mean there has been many times throughout history various philosophies and things were prevalent at the expense of other philosophies, things, and even people that better served problems/society.
@Isti115
@Isti115 4 жыл бұрын
8:30 No, no, no, no, please! Think about generalization, currying! This argument order matches that of Haskell's fold and others. (Everything should be as close to functional programming as possible is my basic approach, because I've seen how helpful that can be over the last several years.)
@r-gart
@r-gart 4 жыл бұрын
You know, that's just your opinion, man.
@Isti115
@Isti115 4 жыл бұрын
@@r-gart Yes, I know, that's why I included that it's "my approach", but I would really like to let others know the importance and value of these concepts and design decisions before they just give up on them saying they're too complicated.
@mattmccarthymusic
@mattmccarthymusic 4 жыл бұрын
Editor having fun at the end!! Haha
@ColinRichardson
@ColinRichardson 4 жыл бұрын
I got my current job because I knew how to use arr.reduce(). So can't be that bad. But that last part, is that not just sequence library?
@ColinRichardson
@ColinRichardson 4 жыл бұрын
He, not anymore. We started from scratch in a different language. But yes I agree with you. They must have been using it as a easy barrier of entry. There was about 25 questions on test. I answered the first 3, 2 of which were reduce, and they stopped there and then. I didn't leave the car park before I was told I had the job (which was nice, but very shocking).
@KelvinWKiger
@KelvinWKiger 4 жыл бұрын
@@ColinRichardson Shocking indeed, reduce is really not that hard compare to a classic sorting algorithm optimization question. Lucky you, keep it up!
@ColinRichardson
@ColinRichardson 4 жыл бұрын
Sorting algorithm questions would not help that much here.. We don't do sorting on our data. Ordered by edited order. More recent it was edited, the higher in the list it is.. Full Stop. :D Maybe I got the job on my sexy looks instead. Though, I have 2 games companies for past jobs on my CV. I found that to almost be like a "Get into any job you want easily" pass.
@KelvinWKiger
@KelvinWKiger 4 жыл бұрын
@@ColinRichardson Aaaaah... The sexy look, now your story makes sense.
@ColinRichardson
@ColinRichardson 4 жыл бұрын
And my modesty.. I am the most modest person to have ever existed. :D
@Zorgatone
@Zorgatone 4 жыл бұрын
At 15:18 there’s an error in the events refactored with fromEntries and entries (namely .bind(this, value) .bind(this, key))
@naythaniel
@naythaniel 4 жыл бұрын
The max number of function arguments seems to be just memory limited. So it would probably end up with the same result for any given array of values in the Math.max example. No?
@31redorange08
@31redorange08 4 жыл бұрын
I think I've hit the limit before.
@mithunsatheesh
@mithunsatheesh 4 жыл бұрын
A talk emphasising code readability where none of the code samples shown are actually readable by human eye. Very unique !!.
@truvc
@truvc 4 жыл бұрын
For the data.notifications.edge, where they’re trying to get the number of unseen notifications the .map() seems unnecessarily complicated. You could filter out the falsy and unseen notifications in .filter().
@KevinFarrugia
@KevinFarrugia 4 жыл бұрын
I think that readability is subjective and dependent on what you are used to. People used to say that JSX is hard to read but now have gotten accustomed to it.
@impero101
@impero101 4 жыл бұрын
I completely agree. People coming from a OOP or imperative background, will rate readability differently than people coming from a functional, declarative background.
@jessepoulton224
@jessepoulton224 4 жыл бұрын
Don't even need the .map, no? `edges.filter(v => v && v.IsSeen).length`
@roceb5009
@roceb5009 4 жыл бұрын
I feel like people wouldn't use reduce as a replacement for for loops if reduce wasn't just a wrapper for a for loop and an accumulator. like, if it actually did a proper MPI/MapRedeuce-style reduce instead of this iterative accumulator-based implementation
@franklemanschik_de
@franklemanschik_de 4 жыл бұрын
@14:20 your pointing out functions do cost nothing but thats not correct it depends on the call order and pushes and pops the call stack as also creating context objects :) they have cost and i boost performance and read ablitity via reducing function invocations and replace them with apply on the same context,
@kettlebellsporttraining1507
@kettlebellsporttraining1507 4 жыл бұрын
I would say that the reduce method should be considered , per se, a language feature that aims to convey a peculiar meaning like: I’m going to iterate over something and transform it into something else. So, when we encounter a reduce statement, we know right from the start what it stands for, and this fact should be taken into account while talking about code readability. Moreover I think that the readability problems arising from the reduce function are more tied to the “indiscriminate” use of anonymous arrow functions or impure functions or simply bad or not reader friendly Javascript. Simply defining a named function or declaring a named arrow function increases in a significant way the readability of the code (not to mention that it makes things easier to test when needed). So I would not put the reduce method to sleep, not just yet..
@dassurma
@dassurma 4 жыл бұрын
We didn’t say to put it to sleep. As we said multiple times, put it in a named function to make it expressive.
@Nielsblog
@Nielsblog 4 жыл бұрын
20:26 This is probably my most common usage for .reduce(). I don't see how the proposed alternative is better. I expect that other people can read what .reduce does, since this does require you to read it inside-out like some of the other examples. And most importantly, unlike the alternative you only do the iteration once, making it a simple O(n) operation instead of O(n + n). (Sorry, had to look smart at the end there, it comes with using .reduce() all the time).
@dassurma
@dassurma 4 жыл бұрын
Well, as I said in the video, it is _sometimes_ used as a performance optimization, bu I highly doubt your array is long enough to sacrifice expressiveness for the couple of nanoseconds that you gain. (Also O(n+n) is the same as O(n), just sayin’)
@HawkingsCt
@HawkingsCt 4 жыл бұрын
If you're concerned about optimization you should use a loop instead of reduce
@Nielsblog
@Nielsblog 4 жыл бұрын
@@dassurma My main argument is that is this instance I find reduce _more_ expressive than the proposed alternative.
@dassurma
@dassurma 4 жыл бұрын
@@Nielsblog I hear ya. I think that _might_ apply to functional programming languages. And maybe if you choose to write functional-only on JavaScript, that might be the right way to go for your project. In general I don’t consider JavaScript a functional programming language and find reduce() less idiomatic than a simple loop. That’s why I wanted to look at code examples from real code bases. I found those definitely less readable than the imperative equivalent.
4 жыл бұрын
Interesting episode but I wish there were some examples of good use case for reduce function.
@jakearchibald
@jakearchibald 4 жыл бұрын
It's ok for accumulating totals
@soulehshaikh8799
@soulehshaikh8799 4 жыл бұрын
Yes, I always read video descriptions especially if it is from a leading tech firm channel like Google.
@a9jc14
@a9jc14 3 жыл бұрын
Is the presentation or list that they use in this episode available?
@mokkamokka4097
@mokkamokka4097 4 жыл бұрын
I love you guys!
@danylogudz
@danylogudz 4 жыл бұрын
19:51 should count “not seen”, but implementation counts “seen” But the way is understandable
@j3bb9z
@j3bb9z 4 жыл бұрын
Also, there is missing "node" key (destructured in original implementation). And also, there is no need to map before filtering. data.notifications.edges .filter(edge => edge?.node?.isSeen === false) .length; But yeah, still easier to read without the reduce. I think.
@dassurma
@dassurma 4 жыл бұрын
Ah yeah, both comments here right. But you get the gist :D
@Tolgeros
@Tolgeros 4 жыл бұрын
Try iteratively building a Promise chain (NOT a Promise.all) without reduce. With reduce, it's trivial: const pChain = MAPPING_ARRAY.reduce((p, mapping) => { return p.then(() => { /* create and return a promise using mapping */}) }, Promise.resolve())
@jakearchibald
@jakearchibald 4 жыл бұрын
I prefer async/await for this developers.google.com/web/fundamentals/primers/async-functions#example_outputting_fetches_in_order
@leonnilein
@leonnilein 4 жыл бұрын
What do you think about .filter(f => !!f) instead of .filter(Boolean)? More expressive, less expressive, antipattern?
@dassurma
@dassurma 4 жыл бұрын
None of these patterns are great, tbh
@jakearchibald
@jakearchibald 4 жыл бұрын
There's also f => f == true, but yeah, few good options
@MaxArt2501
@MaxArt2501 4 жыл бұрын
I think the most expressive code would be .filter(s => s !== 0) or something like that. Double bangs are a bit jarring, as well as .filter(Boolean) (that I'm giulty of using from time to time).
@GreenZ3r0
@GreenZ3r0 4 жыл бұрын
What about? xyz.EXISTS_FILTER = Boolean; xyz.UNIQUE_FILTER = ...; ... array.filter(xyz.EXISTS_FILTER)
@jsmunroe
@jsmunroe 6 ай бұрын
I've been coding for 20+ years as well, and I understand reduce really well, but I've never wanted to use it because it is so muddy.
@MrKarameyl
@MrKarameyl 4 жыл бұрын
Even if JavaScript is not a pure functional language, it does not mean that writing in functional style is less readable because in case of the first function, this would be far more readable in my opinion. repl.it/repls/RecentFormalPup Just because you read and master reduce does not mean you master functional programming. It is a really small water droplet in the ocean of features that functional programming offers.
@dassurma
@dassurma 4 жыл бұрын
I didn't say less readable. I said less idiomatic.
@Isusia
@Isusia 4 жыл бұрын
If someone worried about intermediate arrays there is another approach called transducers. But them are even more complicated than a reducers. Can you made another video about them, bring some light and your opinion? Thank you.
@kerbatonbaton8108
@kerbatonbaton8108 3 жыл бұрын
8:38 does not work like intended? if i input [1, 2, 3, 1] i get back [1, 2, 4, 7, 8] but it should be [1, 3, 6, 7] function relativeToAbsolute(input) { return input.reduce((arr, val) => { return arr.concat([arr[arr.length-1] + val]); }, [input[0]]); } relativeToAbsolute([1, 2, 3, 1])
@blenderpanzi
@blenderpanzi 2 жыл бұрын
20:06 But very strictly speaking this is **not** functional. Calling methods is object orientated. Functional would be having nested function calls.
@josephwong2832
@josephwong2832 4 жыл бұрын
That was a great debate. I've always had to spend extra time wrapping my head around reduce any time I use or see it.
@KarlOlofsson
@KarlOlofsson 2 жыл бұрын
I used reduce to go through every element and select the largest recently. A more readable way would have been to have a variable for the end result, and a loop comparing and storing any new larger value, but it seemed so messy. Any suggestions for a more readable but equally concise/functional way to solve this? :)
@valour.se47
@valour.se47 4 жыл бұрын
I always read the description of videos longer then 20 minutes to find the TL;DR version.
@sidvishnoi1480
@sidvishnoi1480 4 жыл бұрын
There is also a proposal (Stage 2) for iterator helpers: github.com/tc39/proposal-iterator-helpers, which should counter the intermediate object argument.
@dassurma
@dassurma 4 жыл бұрын
Oh NICE! I did no know about this proposal.
@stepankrivanec4644
@stepankrivanec4644 4 жыл бұрын
Hello beautiful people at @Google Chrome Developers The code shown on 7:36 does not produce expected result (the one in code comment) The code given there will return [1, 2, 4, 7, 8] not [1, 3, 6, 7] for input of [1, 2, 3, 1] Have a nice day.
@the-old-channel
@the-old-channel 4 жыл бұрын
What if I need to flat an object with some additional parsing, is it ok to use reduce? rows.reduce((a, b) => { const object = JSON.parse(b["data"]); return { ...a, ...object }; }, {});
@jakearchibald
@jakearchibald 4 жыл бұрын
This performs pretty badly, like O(n^2) badly. A regular loop will be much faster, and easier to read.
@welltypedwitch
@welltypedwitch 4 жыл бұрын
@@jakearchibald I would disagree about the readability, but why would a loop be that much faster?
@jakearchibald
@jakearchibald 4 жыл бұрын
@@welltypedwitch because a regular loop would only create one object, whereas this reduce example is creating n, and performs two inner iterations for every outer iteration
@joe_navy_s3
@joe_navy_s3 4 жыл бұрын
I use reduce() if the resulting array is a reduced version of the initial array
@Luxalpa
@Luxalpa 4 жыл бұрын
Use filter()
@joe_navy_s3
@joe_navy_s3 4 жыл бұрын
@@Luxalpa yeah but i meant to say the resulting answer is a reduced version of the initial array, as in (filter+map)
@FireNeslo
@FireNeslo 4 жыл бұрын
Main problem with reduce is the arguments being in the wrong order. To me that's the main unreadable part otherwise it would mostly read like a loop.. Reducing state based on events for example can be very nice.
@Luk4zs
@Luk4zs 4 жыл бұрын
they are not in the wrong order
@TheHeadlets
@TheHeadlets 4 жыл бұрын
@@Luk4zs Of course they are. They even explained it in the video - callbacks always go last as by their nature they are called back last. It's the same with `setTimeout` and `setInterval` where the callback is first for seemingly no reason.
@Luk4zs
@Luk4zs 4 жыл бұрын
@@TheHeadlets Well, the accumulator parameter is optional, therefor it's after callback parameter, so they are not in wrong order.
@LowPolyPixel
@LowPolyPixel 4 жыл бұрын
I don't think I've ever used reduce(). But that's because I usually forget it exists and it feels really unintuative when I do remember its existence.
Weak JavaScript - HTTP 203
29:22
Chrome for Developers
Рет қаралды 25 М.
Top 10 performance pitfalls - HTTP 203
36:31
Chrome for Developers
Рет қаралды 37 М.
Happy birthday to you by Secret Vlog
00:12
Secret Vlog
Рет қаралды 6 МЛН
كم بصير عمركم عام ٢٠٢٥😍 #shorts #hasanandnour
00:27
hasan and nour shorts
Рет қаралды 4,7 МЛН
Four silly browser hacks - HTTP 203
21:01
Chrome for Developers
Рет қаралды 39 М.
How to Get a Developer Job - Even in This Economy [Full Course]
3:59:46
freeCodeCamp.org
Рет қаралды 3,1 МЛН
3.143 ways to synchronize data across documents - HTTP 203
16:21
Chrome for Developers
Рет қаралды 21 М.
CMD - Command Prompt Training for IT Professionals (Full Course)
3:18:32
Jobskillshare Skills-Based Platform
Рет қаралды 1,4 МЛН
Cross-origin fetches - HTTP 203
23:42
Chrome for Developers
Рет қаралды 39 М.
The Strange Physics Principle That Shapes Reality
32:44
Veritasium
Рет қаралды 6 МЛН
Is postMessage slow? - HTTP 203
21:09
Chrome for Developers
Рет қаралды 22 М.
Errichto Stream, POI 22/1
3:55:08
Errichto Algorithms
Рет қаралды 170 М.
JavaScript for-loops are… complicated - HTTP203
14:17
Chrome for Developers
Рет қаралды 106 М.
JavaScript counters the hard way - HTTP 203
24:08
Chrome for Developers
Рет қаралды 42 М.