37
loading...
This website collects cookies to deliver better user experience
Array.reduce()
method and then how to simplify things using for..of
.const data = [
{
name: "Project 1",
completed: "01-2021"
},
{
name: "Project 2",
completed: "02-2021"
},
{
name: "Project 3",
completed: "02-2021"
},
{
name: "Project 4",
completed: "02-2021"
}
];
Array.reduce
takes two parameters, a function which is called for each element in the array and an initial value for the return value of the operation. Array.reduce()
should have the following signature (accumulator, currentValue, index, array) => {...}
. accumulator
is a value which is carried over from the previous calls to the function, currentValue
is the value in the array we are currently at, index
is the index we are currently at, and array
is the array reduce was called on. You can omit index
and array
if you have no use for them.currentValue
to shape accumulator
how we want until we have looped through all the values in the array. The return value of the function is set as the new value of the accumulator
for the next iteration.accumulator
is returned as the return value of reduce.const projectsByMonth = data.reduce((result, project) => {
const existingProjects = result[project.completed] || [];
return {
...result,
[project.completed]: [...existingProjects, project]
}
}, [])
/*
{
'01-2021': [ { name: 'Project 1', completed: '01-2021' } ],
'02-2021': [
{ name: 'Project 2', completed: '02-2021' },
{ name: 'Project 3', completed: '02-2021' },
{ name: 'Project 4', completed: '02-2021' }
]
}
*/
Array.reduce
gets the job done just fine, but the code is not the easiest to understand. While this example is a simple one, I almost always struggle to wrap my head around complex code which uses reduce. Could we make this better?for..of
is a way to loop over any iterable in JavaScript. We can use for..or
to solve the same problem by creating the object beforehand and looping through the data.let projectsByMonth = {};
for (const project of data) {
const existingProjects = projectsByMonth[project.completed] || [];
projectsByMonth = {
...projectsByMonth,
[project.completed]: [...existingProjects, project]
}
}
/*
{
'01-2021': [ { name: 'Project 1', completed: '01-2021' } ],
'02-2021': [
{ name: 'Project 2', completed: '02-2021' },
{ name: 'Project 3', completed: '02-2021' },
{ name: 'Project 4', completed: '02-2021' }
]
}
*/
Array.push
.let projectsByMonth = {};
for (const project of data) {
const key = project.completed;
if (!(key in projectsByMonth))
projectsByMonth[key] = []
projectsByMonth[key].push(project)
}
for..of
easier to understand, is mostly a matter of taste and familiarity with reduce. However, thinking about clarity of the code we write is an important part of software engineering. Clear, explicit code will help other programmers (or ourselves in a couple of months 😜) understand the code and the reasoning behind it. “Any fool can write code that a computer can understand. Good programmers write code that humans can understand.”
Martin Fowler