DEV Community

Cover image for Array.reduce() is Goated 🐐✨

Array.reduce() is Goated 🐐✨

Matt Lewandowski on May 14, 2024

The title says it all 🐐. I want to talk about my all-time favorite javascript array method: Array.reduce(). I know there are a lot of contenders ou...
Collapse
 
lionelrowe profile image
lionel-rowe

Counterpoint from Google's Jake Archibald:

All code using array.reduce should be rewritten without array.reduce so it's readable by humans mutes thread
Jake Archibald @jaffathecake

Along with the follow-up YouTube video: Is reduce() bad? - HTTP 203

Collapse
 
realratchet profile image
Ratchet

So can map, forEach, flat, sort, it's non-argument. Everything is readable to human and is a preference. Reduce is a functional construct that exist in all functional languages and is pulled into most imperative languages too. JS should add reduceLeft.

Collapse
 
thathurtabit profile image
Stephen Fairbanks

I'm with Jake. I'd only use Reduce to reduce a list of number to a single value.

Collapse
 
lucasayabe profile image
lucas-ayabe

Except reduce is way more readable if you use it along with functional style code, and think in the computations with a immutable way is easier, once you know both approachs.

I guess that traditional loops are only more readable if you prefer an imperative style of programming or really like procedural paradigm.

Collapse
 
bob_gulian_6f3d7d3a95b61c profile image
Bob Gulian

Reduce Scrooge

Collapse
 
bobdotjs profile image
Bob Bass

Reduce is cool but it's not readable or intuitive which slows down development with teams.

When I see someone at work use reduce, they're usually being clever. I don't like clever when there was a simple option.

I'd almost always prefer to see .filter, .map, or just a good old fashioned for/in or for/of loop with relative mutable variables or arrays/objects defined above it.

Reduce is great, but it gets a 0 for readability and a 0 for simplicity in my book.

Collapse
 
vlackcoder profile image
Ghimmy

Simple is boring atimes... If you name your functions well/add the write comment then it's not a problem.
The only argument you can bring against using reduce is performance...

Collapse
 
bobdotjs profile image
Bob Bass

Respectfully... I'm so glad we don't work together if you're argument is "simplicity is boring".

Also, reduce is never actually used in a readable way. Everyone wants to claim to use best practices but in the wild it's always

acc: any ..., {}

Or something like that.

So you've got poor performance, bad patterns encouraged, and it only takes five times longer to grok.

Thread Thread
 
lucasayabe profile image
lucas-ayabe

reduce actually is the solution when your array methods are slow, because chain map, filter, etc causes more cycles through the array, so you can do all at the same time with a reduce, as any array traversing operation can be expressed by a reduce.

Its called transducers, and a transducer is a really elegant way to express composed array operations.

If you like a imperative style of programming, and/or mainly the procedural paradigm, sure, reduce never will be the more readable solution, but if you program in a declarative way, composing computations, reduce will be more readable than any imperative loop, as you can forget the array, think only in a function that maps one state to the next state, and that will work in the reduce.

Collapse
 
oculus42 profile image
Samuel Rouse

Nice article with great examples!

I especially appreciate the Performance Considerations section, as the creation of object on every loop adds up quickly. Comparing a mutating reducer and a new-object-per-loop reducer, by 1000 entries a "bad" reducer will run for almost ~70 ms, while the object mutation reducer is under 1 ms. With 2000 entries that balloons to ~300 ms while the mutation is still 1 ms!

Collapse
 
mattlewandowski93 profile image
Matt Lewandowski

Thank you!

I'm glad you appreciate that. I've definitely come across this mistake in production applications, where it made a huge difference in render speeds. ~70ms times a few re-renders can be massive.

Collapse
 
xtofl profile image
xtofl

reduce was never intended to cause side-effects (i.e. pushing something onto an array you're not certain is owned by you alone). Yet, mutating the accumulator is the only solution to the performance caveat.

Interestingly, functional programming flavored C++ counters the same problem by using something called 'linear types': data types that support 'growing' into new versions of themselves.

I heard it first at meetingcpp.com/mcpp/slides/2018/li...

Collapse
 
shhhwepsss profile image
Vildan

For flattening js has flat array method, for unique values set, for map, of course map. s So reduce is one of tools to write your code but not the only one

Collapse
 
mattlewandowski93 profile image
Matt Lewandowski

Yes, this is outlined in the article. It's just another tool that is useful to understand. There will be use cases where it makes more sense to use reduce, and it's important to be able to understand why someone might be using it in a code review.

Collapse
 
cefn profile image
Cefn Hoile • Edited

The commentary suggests you would need .reduce(...) if you wanted to transform along the way, but more intuitive for that would be .flatMap()

Collapse
 
dx0x58 profile image
dx0x58

Hi, thanks for the article!
I want to make a small addition to a case with unique values in an array.
The time complexity for the specified option will be O(n^2)

const numbers: number[] = [1, 2, 3, 2, 4, 3, 5, 1, 6];

const uniqueNumbers: number[] = numbers.reduce((acc, curr) => {
  if (!acc.includes(curr)) {
    acc.push(curr);
  }
  return acc;
}, []);
Enter fullscreen mode Exit fullscreen mode

Because there are two nested array iterations here: .reduce and .include
Which will be very ineffective on large input data.

this can be done in O(n) time using Set:

const numbers = [1, 2, 3, 2, 4, 3, 5, 1, 6];
const uniqueNumbers = [...new Set(numbers)];
Enter fullscreen mode Exit fullscreen mode
Collapse
 
lucasayabe profile image
lucas-ayabe

This is true, but not if you need to deal with non-primitive data like literal objects for example.

Collapse
 
mikec711g profile image
Michael Casile

Great article. Small and well done salesmanship without taking 40% of the article with WHY it's good. Great examples. I've got code where I brute-forced thru some of this ... looking to find the time to do it more elegantly w/reduce.

Collapse
 
marcelc63 profile image
Marcel Christianis

The redux example is mindblowing!

Gave me a whole new perspective on reducers.

Collapse
 
mattlewandowski93 profile image
Matt Lewandowski

I'm glad you appreciated that! I was back and forth on whether or not I should include it, since it's pretty bulky. I really wanted to tie it to redux and also useReducer in React. They become a lot simpler when you understand the core concept.

If you ever build a old-school js game, like chess, and want the application history like redux provides, you can easily achieve like this.

Collapse
 
dscheglov profile image
Dmytro Shchehlov • Edited

@mattlewandowski93
despite Redux uses reducers, array.reduce doesn't implement the Redux store, more than there is no array.reduce in redux dispatch. Even combineReducers doesn't use array.reduce.

But, array.reduce is a good candidate to build the reducing decorator that can handle the batch of actions:

type ActionBatch = { type: string, actions: UnknownAction[] };

const isActionBatch =
  (action: UnknownAction, batchActionType: string): action is ActionBatch =>
    action.type === batchActionType && Array.isArray(action.actions)

const batching = 
  (batchActionType: string) =>
  <S, >(reducer: Reducer<S>): Reducer<S> =>
  (state: S | undefined, action: UnknownAction) =>
    isActionBatch(action, batchActionType)
      ? action.actions.reduce(reducer, state as S)
      : reducer(state, action);

const batch =
  (type: string) =>
  (...actions: UnknownAction[]): ActionBatch => ({ type, actions });
Enter fullscreen mode Exit fullscreen mode

Such approach allows to avoid multiple dispatching (i.e. rendering) and keep initial reducer simple.

The full example here: TS Playground

Collapse
 
marcelc63 profile image
Marcel Christianis

Thanks for writing this!

I've now realized I've been taking the reducer in redux & useReducer for granted.

It's really refreshing to understand the fundamentals of the abstraction that I use daily.

Collapse
 
dscheglov profile image
Dmytro Shchehlov

@marcelc63

Why do you think Redux reducers are named "reducers"? :)))
The concept of Redux is a reducing of actions flow to the current (or final) state.

Collapse
 
seven profile image
Caleb O.

Great article!

if (!acc[curr.age]) {
    acc[curr.age] = [];
  }
  acc[curr.age].push(curr);
  return acc;
Enter fullscreen mode Exit fullscreen mode

This snippet above could've been shortened to this BTW.

acc[key] = acc[key] || []
acc[key].push(curr)
return acc
Enter fullscreen mode Exit fullscreen mode
Collapse
 
harjot_singh_149958c00f62 profile image
harjot singh • Edited

can be further shortened to :

return (acc[curr.age] ??= []).push(curr), acc;
Enter fullscreen mode Exit fullscreen mode
Collapse
 
seven profile image
Caleb O.

Haha! The nullish coalescing assignment!

Collapse
 
vaviloff profile image
Vaviloff

You should check out Perl, haha.

Collapse
 
ripaz profile image
Ripaz

Most of these can be written with for...of/forEach, which will also reduce cognitive complexity it introduces.

const productMap: Record<Product['id'], Product> = {};
products.forEach((product) => product[product.id] = product);

// Or using `Object.fromEntries`
const productMap = Object.fromEntries(
  products.map((product) => [product.id, product])
);
Enter fullscreen mode Exit fullscreen mode

Also, the easy way to check if you should use reduce or regular for loop is to ask one question: will the reduce work the same with and without default value. If yes, then use reduce, otherwise for loop is better choice.

E.g. from examples, this will only work if the default value is empty object

const productMap: { [key: number]: Product } = products.reduce((acc, curr) => {
  acc[curr.id] = curr;
  return acc;
}, {});
Enter fullscreen mode Exit fullscreen mode
Collapse
 
lucasayabe profile image
lucas-ayabe

Well, any array operation that can be expressed by a forEach can be expressed by a reduce, because they abstract almost the same thing. Reduce, or fold, is the abstraction for stateful computations in a world where you can only do stateless computation, so if you ever need to express an forEach in a immutable way, you can do by using a reduce, and if you need to express a reduce in a mutable way you can use a for loop or forEach.

To be fair, at this point, you don't need any array method, as all of them could be expresed as some simple algorithm using for loops.

Its a matter if you prefer imperative or declarative style of programming, and if you really need to optimize for performance or a more elegant code is needed.

Collapse
 
ripaz profile image
Ripaz • Edited

I agree with all what you said, as I have missed to point out why I the forEach/for is better in this case.

The examples in this post are not presenting or using reduce/fold as it was intended, with immutability in mind. For example, if we take into account the function from post

const productMap: { [key: number]: Product } = products.reduce((acc, curr) => {
  acc[curr.id] = curr;
  return acc;
}, {});
Enter fullscreen mode Exit fullscreen mode

It introduces the mutation into the mix, therefore the usage of reduce here is redundant and we have not benefit from it, as we are just passing around the reference of an object. Imagine if we passed default accumulator value for reduce as an variable that we defined previously before using reduce, then effectively, both that variable and reduce's return would be the same object (pointer).

If we created a new object that would not mutate previous one, each time we iterate over the item, then that would be a proper use case of an reduce/fold.

products.reduce((acc, curr) => ({ ...acc, [curr.id]: curr }), {});
Enter fullscreen mode Exit fullscreen mode

Note: there are times where you will need to mutate an value because of performance, but in languages (like JS/TS in this example) where I have a option to use other methods that improve readability; I would rather go with the forEach/for than reduce/fold.

Collapse
 
jdfwarrior_99 profile image
David Ferguson

Don’t get me wrong, I like a good reduce function, but let’s not pretend that the stuff you’re showing off as examples are all easily doable with some of the other array methods, especially a forEach. The primary difference is that with a forEach you have to initialize your state (counter vars and such) outside of the function so that they persist through each iteration of the loop.

I don’t know that I’d use example #8. That’s more easily done with a Set.

Collapse
 
mattlewandowski93 profile image
Matt Lewandowski

Hey @jdfwarrior_99, I am not pretending anything. I am simply showing use cases for the reduce method. There are always going to be many ways to approach any problem. All array methods are like forEach. They're just loops. Having the block scoped variable allows you to easily chain methods.

It can be done with Set, however, it could be beneficial to do it with reduce if you wanted to use the unique variable in the interaction. With Set, you would have to create the set first, then do another iteration of the data to use it. In applications where performance is critical, these things can make a big difference.

Collapse
 
ivan_sapeha profile image
ivan-sapeha • Edited

If we're talking about performance, using for loop always will be faster than any of the array methods

Collapse
 
harris-miller profile image
Harris Miller

Understanding how to do that with reduce is important to knowing how to expand in the idea of unique. Consider a uniqBy function. You can just "use a Set" for that

Collapse
 
vincent_huss_271b29c3eb25 profile image
Vincent Huss • Edited

@mattlewandowski93
Beware though, your approach in example 8 has a quadratic complexity, it will scale very badly performance wise. (It's a loop within a loop). Unless I'm sure I have no more than 10 elements in my array, I would definitely use a Set or a hash map (independently of using reduce or not)

Collapse
 
mitchiemt11 profile image
Mitchell Mutandah

The Redux example is another level! I'm going to try it out ASAP 😎

Collapse
 
whevaltech profile image
Wheval

Okay, now i have to write about my goat method😁

Collapse
 
mindplay profile image
Rasmus Schultz

Several of these examples aren't even reducing anything - you're just doing mutations and returning the same object over and over.

Your code is now slower and unnecessarily convoluted, to the point that you don't even realize when you're just doing an obfuscated .forEach.

Reduce operations are necessary in pure functional programming languages because you don't have mutations - in JavaScript, they're an exercise in futility.

Collapse
 
morganney profile image
Morgan Ney • Edited

I’m skeptical of people who overuse reduce. They tend to be more enamored with overcoming their own difficulties with it, than its usefulness. It often produces hard to read code and is used where there are better alternatives.

All code using array.reduce should be rewritten without array.reduce so it's readable by humans mutes thread.

Another comment beat me too it ☝️

Collapse
 
cefn profile image
Cefn Hoile

Simple rule. If you return the same reference as the accumulator every time, don't use .reduce(...)

Too many of these examples violate that rule and would therefore be simpler, more performant and more readable as a loop.

Collapse
 
olsondev profile image
Josh Olson • Edited

Yeah, no thanks. Reduce sucks compared to a simple loop or a method with a more intuitive name. We want the sum? Let's call it sum. We want to sum by something nested? How about a map and then a sum? Or a sumBy?

All of your other examples are terrible. Sorry, I'm not sugar-coating it. This was clickbait garbage.

Collapse
 
fernal73 profile image
Linus Fernandes
#!/usr/bin/env ts-node
/* eslint-disable @typescript-eslint/no-explicit-any */
const numbers: number[] = [ 1, 2, 3, 4, 5 ];
const sum: number = numbers.reduce((acc, curr) => acc + curr, 0);
// Output: 15
console.log(sum);

const nestedArray: number[][] = [ [ 1, 2 ], [ 3, 4 ], [ 5, 6 ] ];
const flattenedArray: number[] =
    nestedArray.reduce((acc, curr) => acc.concat(curr), []);
// Output: [1, 2, 3, 4, 5, 6]
console.log(flattenedArray);

interface Person {
  name: string;
  age: number;
}

const people: Person[] = [
  {name : "Alice", age : 25}, {name : "Bob", age : 30},
  {name : "Charlie", age : 25}, {name : "Dave", age : 30}
];

type GroupedByAge = Record<number, Person[]>;

const groupedByAge: GroupedByAge = people.reduce((acc, curr) => {
  if (!acc[curr.age]) {
    acc[curr.age] = [];
  }
  acc[curr.age].push(curr);
  return acc;
}, {} as GroupedByAge);

/*
Output:
{
  '25': [{ name: 'Alice', age: 25 }, { name: 'Charlie', age: 25 }],
  '30': [{ name: 'Bob', age: 30 }, { name: 'Dave', age: 30 }]
}
*/
console.log(groupedByAge);

interface Product {
  id: number;
  name: string;
  price: number;
}

const products: Product[] = [
  {id : 1, name : "Laptop", price : 999},
  {id : 2, name : "Phone", price : 699},
  {id : 3, name : "Tablet", price : 499},
];

type ProductMap = Record<number, Product>;
const productMap: ProductMap = products.reduce((acc, curr) => {
  acc[curr.id] = curr;
  return acc;
}, {} as ProductMap);

/*
Output:
{
  '1': { id: 1, name: 'Laptop', price: 999 },
  '2': { id: 2, name: 'Phone', price: 699 },
  '3': { id: 3, name: 'Tablet', price: 499 }
}
*/
console.log(productMap);

// Accessing a product by ID
const laptop: Product = productMap[1];
// Output: { id: 1, name: 'Laptop', price: 999 }
console.log(laptop);

const fruits: string[] =
    [ "apple", "banana", "apple", "orange", "banana", "apple" ];

type FruitCount = Record<string, number>;
const fruitCounts: FruitCount = fruits.reduce((acc, curr) => {
  acc[curr] = (acc[curr] || 0) + 1;
  return acc;
}, {} as FruitCount);

/*
Output:
{
  'apple': 3,
  'banana': 2,
  'orange': 1
}
*/
console.log(fruitCounts);

type MathFn = (_x: number) => number;
const add5: MathFn = (x) => x + 5;
const multiply3: MathFn = (x) => x * 3;
const subtract2: MathFn = (x) => x - 2;

const composedFunctions: (MathFn)[] = [ add5, multiply3, subtract2 ];

const result: number = composedFunctions.reduce((acc, curr) => curr(acc), 10);
// Output: 43
console.log(result);

interface State {
  count: number;
  todos: string[];
}

interface Action {
  type: string;
  payload?: any;
}

const initialState: State = {
  count : 0,
  todos : [] as string[],
};

const actions: Action[] = [
  {type : "INCREMENT_COUNT"},
  {type : "ADD_TODO", payload : "Learn Array.reduce()"},
  {type : "INCREMENT_COUNT"},
  {type : "ADD_TODO", payload : "Master TypeScript"},
];

const reducer = (state: State, action: Action): State => {
  switch (action.type) {
  case "INCREMENT_COUNT":
    return {...state, count : state.count + 1};
  case "ADD_TODO":
    return {...state, todos : [...state.todos, action.payload ]};
  default:
    return state;
  }
};

const finalState: State = actions.reduce(reducer, initialState);
/*
Output:
{
  count: 2,
  todos: ['Learn Array.reduce()', 'Master TypeScript']
}
*/
console.log(finalState);

const nums: number[] = [ 1, 2, 3, 2, 4, 3, 5, 1, 6 ];

const uniqueNumbers: number[] = nums.reduce((acc, curr) => {
  if (!acc.includes(curr)) {
    acc.push(curr);
  }
  return acc;
}, [] as number[]);

// Output: [1, 2, 3, 4, 5, 6]
console.log(uniqueNumbers);

const grades: number[] = [ 85, 90, 92, 88, 95 ];

const average: number = grades.reduce((acc, curr, index, array) => {
  acc += curr;
  if (index === array.length - 1) {
    return acc / array.length;
  }
  return acc;
}, 0);

// Output: 90
console.log(average);
Enter fullscreen mode Exit fullscreen mode

Updated the examples since some examples were throwing typescript errors.

Collapse
 
moraym profile image
Moray Macdonald

Great article! Ignore the reduce haters, it's an incredibly useful function and any JS developer at mid level or above should be able to understand it. I'd recommend that you don't use acc and cur as your variable names in future though, give them more descriptive names to make it easier for people who haven't read this article to understand what's going on.

On the subject of incredibly useful JS features, I'd update example 4 to use a Map instead of an regular object. It's a really useful data structure designed for EXACTLY this purpose, and the way Map.set works means that you can do the whole thing in one line:

interface Product {
  id: number;
  name: string;
  price: number;
}

const products: Product[] = [
  { id: 1, name: 'Laptop', price: 999 },
  { id: 2, name: 'Phone', price: 699 },
  { id: 3, name: 'Tablet', price: 499 },
];

const productMap = products.reduce(
  (map, p) => map.set(p.id, p),
  new Map<number, Product>(),
);
Enter fullscreen mode Exit fullscreen mode

(OK I lied, it's clearer on multiple lines on such a narrow comment box!)

Finally, when you're using Typescript you should know that reduce can take a type argument, so you can make things neater by writing

const result = arr.reduce<string[]>((a, c) => {...}, [])
Enter fullscreen mode Exit fullscreen mode

instead of

const result = arr.reduce((a, c) => {...}, [] as string[])
Enter fullscreen mode Exit fullscreen mode

or

const result: string[] = arr.reduce((a, c) => {...}, [])
Enter fullscreen mode Exit fullscreen mode

It doesn't exactly save characters, but it makes things much more readable, and (I think?) slightly easier for the compiler to understand.

Collapse
 
pierre profile image
Pierre-Henry Soria ✨

Outstanding read Matt! 🐐 From flattening nested arrays into a single one till the average calculation, your examples are great. I like the Use Case 7, using reduce() to implement a very simple state management (although, limited of course). But no libraries required with reduce()! 🚀

Collapse
 
schmoris profile image
Boris

Saved this article in my reading list and today I was very glad about it, because I remembered the lookup map. Came back, read it again and solved my problem immediately without constructing some kind of weird for loop.

Collapse
 
miryeh profile image
Miri Yehezkel

Interesting article, gives a good amount of examples on how reduce is coded.
Some things didn't sit well, such as finding unique values - the reduce would basically loop over the array every iteration rather than using a set?

What I gather from it is, here are ways to use reduce, and here are example of how you might misuse reduces. Really interesting article!

Collapse
 
vincent_huss_271b29c3eb25 profile image
Vincent Huss • Edited

I'm shared,
One counter argument I have against reduce is that it's a constrained version of what a classic loop let you do (the loop that is implemented within the reduce function). Why use a constrained and less universal way of doing something ?

Edit : that might be controversial but I actually don't think it's a good thing when a language has (or encourages) multiple ways of doing one thing. Having developers aligned on one similar way of doing something is what speed up efficiency in a big team.

Another note on performance (although it might be negligeable I'm not sure) is that you have the function call overhead at each iteration.

Last one, in favour of reduce this time, it encourages to scope the intermediate variables inside the callback function, leaving only the main array variable visible in the main scope.

Collapse
 
lucasayabe profile image
lucas-ayabe

If you think this way, you'll never use any abstraction, more universal things are good to be building blocks as this makes them more composable, but to do the actual work and make easier to reason and think about our code, we need to abstract things to loose the cognitive load of our brains.

This counter argument could be used for any array method, as all of them are abstractions for 20 ~ 30 max LoC algorithms. Why would you use an filter method if you can just use a for with a if inside? Its the same logic.

Any time you use an for loop in an array thats not for just traversing it (like to show item by item of the array), what you're doing is an array operation, and all array operations can be expressed by an reduce, so i can flip the your argument, and ask why would i ever prefer an imperative loop instead of a concat operation inside a reduce without the boilerplate?

All the times you make something like this:

let sum = 0;

for (x of numbers) {
  sum += x;
}
Enter fullscreen mode Exit fullscreen mode

or in a more abstract way:

let accumulator;

for (const item of array) {
  accumulator = join(accumulator, item);
}
Enter fullscreen mode Exit fullscreen mode

In other words, an stateful operation while traversing the array, and they occour a lot, you always will need to repeat the same boilerplate code, so in these cases you can replace all the boilerplate by a reduce, as you only need to think about the concat logic of a type. Once you think the reduce as a concat of all the items of an array, it becomes much more readable than any for loop for the same logic, ex:

const add = (x, y) => x + y;
xs.reduce(add, 0);

// or

xs.reduce((x, y) => x + y, 0);
Enter fullscreen mode Exit fullscreen mode

I like 2 articles that sold the concept for me, and I hope they are of use to you too:
web.archive.org/web/20220325111509...

web.archive.org/web/20220325111821...

Collapse
 
roch_deschaseaux_5bf035dd profile image
Roch Deschaseaux • Edited

Use case 6 composing fonction would be better if it created a new reusable fonction :
const add5 = (x: number): number => x + 5;
const multiply3 = (x: number): number => x * 3;
const subtract2 = (x: number): number => x - 2;

const functions: ((x: number) => number)[] = [add5, multiply3, subtract2];

const composedFunction = functions.reduce((acc, curr) => input => curr(acc(input)));

const result = composedFunction(10);
console.log(result); // Output: 43

Collapse
 
bob_gulian_6f3d7d3a95b61c profile image
Bob Gulian

Good article. I’m a huge fan of reduce, use it everywhere. The ‘redux’ example is clever but not real world, in my opinion. RTK really puts it together in a performant way.

I also think reduce is just fun. I love figuring out how to solve new problems with it and the payoff…if you use it correct it is pure functional, input an array and get a brand new …. Something!

Collapse
 
jlopez788 profile image
Juan Lopez

In c# there's an aggregate extension for IEnumerables, ie arrays. Years ago, it dawned on me that if I have an array of delegates and you can use a state with error checking feature you can create another aggregate extension method to check for the error across all of the delegates. If one fails you stop the iteration and fail early keep the error state and return back to caller that state. All of the if statements collapse beautifully!

Collapse
 
wiley19 profile image
Wilson

Using reduce with objects is inefficient. Use with non-object arrays.

Collapse
 
davod01 profile image
Davod01

i loved your example

Collapse
 
getsetgopi profile image
GP

Great examples and Thank you for sharing!

Collapse
 
shricodev profile image
Shrijal Acharya

Love it. 👌

Collapse
 
gfouz profile image
Giovani Fouz

Great controversy has aroused from this matter. But it is good to learning.

Collapse
 
print_ana profile image
Ana Carolina

That really blew my mind, my favorite case was the third one because I'm always doing this at my job and I loved the way to do it with reduce, it's so much better! Thank you for the tips

Collapse
 
efpage profile image
Eckehard

We are so happy you did not fall in love with any of the other methods of Javascript.

Collapse
 
jangelodev profile image
João Angelo

Hi Matt Lewandowski
Your tips are very useful
Thanks for sharing

Collapse
 
afzalhussein profile image
Syed

I liked the idea of using Reduce for these use cases, however, there's always case for right too for the right job. It's up to developer to decide what's important atm.

Collapse
 
moong23 profile image
Moonki Kim

Nice article! had earned lots of insight from yours :)
Want to know if it is okay to translate this article and upload to Korean dev community

Collapse
 
chivicks_hazard profile image
Victor Chigbo

Wow
I never knew about this.
Thank you @mattlewandowski93

Collapse
 
gateskennedy profile image
Conor Kennedy

Well done

Collapse
 
fractiunate_gh profile image
Fractiunate// David Rahäuser

Nice repertoire ♥

Collapse
 
amendra_rajput_3aa29ee043 profile image
Amendra Rajput

Not using filters now I can use reduce method

Collapse
 
dedodev profile image
Daniele • Edited

Too complex for my level 😭 thanks for sharing

Collapse
 
borges_filho_df3a53d62371 profile image
Borges Filho

Excelent really the explication totally.

Collapse
 
borges_filho_df3a53d62371 profile image
Borges Filho

Really and totally excelent.Very good.

Collapse
 
omeratayilmaz profile image
Ömer Atayilmaz

great explanation!

Collapse
 
dennis_lee_4729f11f3fd3cf profile image
Dennis Lee

I think reduce is cool, however it's not used usefully.