Dart on focus: Reduce vs. Fold

Felipe Emídio
3 min readJan 31, 2023

Reduce to keep the type, fold to change it

Article’s panel with the title written in it

Have you ever wanted to gather a list's elements into something new?

All the Iterable classes, like Lists or Sets, have this option. Dart gives us two reducers functions: reduce() or fold().

What is a “Reducer”?

The word "reducer" is a popular term for React.js developers since its main state management tool, called Redux, works with the reducer concept.

Reducers are functions that take the current state and an action as arguments and return a new state result. — redux.js.org

In my understanding… A function that reduces/shrinks/joins a group of information in a single new value.

Without a reducer

If you want to know the sum of values in a list of integers, we can do as follows.

This code results on:

36

With Reducers

To make the previous code a bit more professional, we can use reducers:

This way is more “reduced”, don't you think? hahaha. =)

And it still gives the correct answer.

36

Let’s take a close look at how it works.

The reduce function receives a callback with 2 parameters: value and element.

  • value: The returned value of the callback. Its initial value is the first element of the Iterable.
  • element: the current element of the iteration.

It iterates through the list starting with index 1. Why not index 0? Because the value variable's initial value is the array's first element.

We can decode with this with prints.

Now check the outputs:

value: 4, element: 8
value: 12, element: 12
value: 24, element: 3
value: 27, element: 0
value: 27, element: 9
36

Our array has a length of 6, but there are just 5 prints. Note how the value starts with the first element and changes to the callback's returned value.

What about the fold?

The fold function works by the same logic but with an important difference.

The reduce always returns the same type as the Iterable, fold doesn’t.

In the example, we had a List of integers. So we could create a new integer value from it.

If you have a list of names and want to count which are duplicated, we can do this with the fold.

The output of the fold example is:

{Dante: 2, Mario: 2, Luigi: 1, Kratos: 1}

This time I changed the name of variables and parameters to be more clear. Two important things here that differ from the reduce function.

First, the fold needs to be typed. Note how the function was written: fold<Map<String, int>>(…) means that our newly generated value will be a Map with string keys and integer values.

Second, the fold receives another parameter before the callback. Can you see the {}? That sets the initial value of the iteration.

When using each one?

Depend on the type of value you want to create. If it is the same type as the Iterable class, we should work with the reduce, and if not, work with the fold.

Also, the fold function is probably the right choice when you want a custom initial value.

Conclusion

Dart gives us a variety of functions ready to be used. We should try to understand each one and apply them smartly.

How the reduce logic works is an interesting subject and can be found in others programming languages in array-like data structures. Cross-technologies knowledge is usually useful.

You can run the codes used on DartPad online. Try to play with the possibilities to help you to deepen your understanding.

If you want to read more of my thoughts and programming tips, then check out my articles and follow me for upcoming content.

--

--

Felipe Emídio

Front-end developer searching for a better version of my code.