This content originally appeared on Go Make Things and was authored by Go Make Things
A few months ago, I saw someone one Twitter ask:
Can we create an object by looping on some data ?
Today, I wanted to write about how to do just that. Let’s dig in!
An example of some data
Let’s imagine you got back an array of data from an API service called WizardSchool. It provided you with a list of wizards.
Each wizard in the array is itself an object that contains the wizard’s name, and an array of spells that they know how to cast.
let wizards = [
{
name: 'Merlin',
spells: ['dancing teacups', 'talk to animals', 'summon owl', 'teleport']
},
{
name: 'Gandalf',
spells: ['light', 'you shall not pass', 'teleport']
},
{
name: 'Radagast',
spells: ['talk to animals', 'summon owl', 'heal']
}
];
You want to create an object from this data, where each key is the name of a spell, and it’s value is an array of wizards who can cast it.
// The end result should look something like this...
let spells = {
'dancing teacups': ['Merlin'],
'talk to animals': ['Merlin','Radagast'],
'summon owl': ['Merlin','Radagast'],
'teleport': ['Merlin','Gandalf'],
'light': ['Gandalf'],
'you shall not pass': ['Gandalf'],
'heal': ['Radagast']
};
Let’s look at two ways to do that!
Loop and push
The most straightforward way to do this is by looping over the array, either with a for...of
loop or the Array.forEach()
method.
for (let wizard of wizards) {
// Do stuff...
}
We’ll create an empty object for our spells
.
Then, on each loop, we’ll loop through each of the spells
for the wizard
. If spells
object does not contain that spell
, we’ll create it, and assign an array with the wizard.name
. Otherwise, we’ll add the wizard.name
to the array.
// The spells data
let spells = {};
// Loop through each wizard
for (let wizard of wizards) {
// Loop through each spell
for (let spell of wizard.spells) {
// If the spell doesn't exist, add it
// Otherwise, add the wizard
if (!spells[spell]) {
spells[spell] = [wizard.name];
} else {
spells[spell].push(wizard.name);
}
}
}
Now, our spells
object contains all of the spells, and the wizards who can cast them.
Array.reduce()
The Array.reduce()
method takes the content of an array and returns a single value. That value can be anything: a string, number, object, or even another array.
The Array.reduce()
method accepts two arguments: a callback
method to run against each item in the array, and a starting
value.
The callback
also accepts two arguments: the accumulator
, which is the current combined value, and the current
item in the loop. Whatever you return
is used as the accumulator
for the next item
in the loop. On the very first loop, that starting
value is used instead.
Let’s rewrite our simple loop above using Array.reduce()
.
let spells = wizards.reduce(function (obj, wizard) {
// Loop through each spell
for (let spell of wizard.spells) {
// If the spell doesn't exist, add it
// Otherwise, add the wizard
if (!obj[spell]) {
obj[spell] = [wizard.name];
} else {
obj[spell].push(wizard.name);
}
}
return obj;
}, {});
This eliminates the need to create a separate spells
object and then loop. You can combine both steps into a single method.
Personally, though, I find the loop and push approach simpler and easier to read… and I’m not alone! Jake and Surma from Google’s HTTP 203 podcast have shared similar thoughts in the past.
Which approach should you use?
Ultimately, whichever one is easier for you to read and maintain.
For me, that’s the loop and push options, but it’s good to have options if you want them.
? A new session of the Vanilla JS Academy starts on October 4. Let's make 2021 the year you master JavaScript. Click here to join.
This content originally appeared on Go Make Things and was authored by Go Make Things
Go Make Things | Sciencx (2021-09-24T14:30:00+00:00) How to create an object from an array of data. Retrieved from https://www.scien.cx/2021/09/24/how-to-create-an-object-from-an-array-of-data/
Please log in to upload a file.
There are no updates yet.
Click the Upload button above to add an update.