Reputation: 5985
I am trying to create an object from a forEach
loop in javascript and in this simple object, I am trying to add up all of the count
s for each item in the array.
Currently, I'm using firebase in an ionic (angular/typescript) project and I am returning an array of items from firebase. The array looks something like this:
[
{
id:'uniqueID',
specs: {
count:5,
forSale:false,
group:"qPELnTnwGJEtJexgP2qX",
name:"Foxeer Cam 2",
type:"camera"
}
},
{
id:'uniqueID',
specs: {
count:4,
forSale:false,
group:"qPELnTnwGJEtJexgP2qX",
name:"Furibee 40a",
type:"esc"
}
},
{
id:'uniqueID',
specs: {
count:4,
forSale:false,
group:"qPELnTnwGJEtJexgP2qX",
name:"Runcam Cam 1",
type:"camera"
}
},
{
id:'uniqueID',
specs: {
count:1,
forSale:false,
group:"qPELnTnwGJEtJexgP2qX",
name:"Hobbywing 4 in 1",
type:"esc"
}
}
]
Here's how I'm running through these items (result
being the list of items):
let partArr = [];
let typeObj = {};
result.forEach(part => {
//Put all parts in a list
partArr.push({
'id':part.id,
'specs':part.data(),
});
//Put all types in a list
typeObj[part.data().type] = {
'count': 0
};
});
Now, I need to increment the count, adding each part's count to the last depending on their type. The typeObj
should look something like this.
{
esc: {
count:5
},
camera: {
count:10
}
}
I tried adding the count to the count like so:
typeObj[part.data().type] = {
'count': typeObj[part.data().type].count + part.data().count
};
but it does not recognize there being a count when I'm first making the object. (I think).
Any advice?
Upvotes: 0
Views: 236
Reputation: 370729
It would probably be easier to use reduce
to generate the object with the counts all at once, and to call .data()
only once on each iteration:
const results = [
{
data() { return { specs: {
count:5,
forSale:false,
group:"qPELnTnwGJEtJexgP2qX",
name:"Foxeer Cam 2",
type:"camera"
}}}},
{
data() { return { specs: {
count:4,
forSale:false,
group:"qPELnTnwGJEtJexgP2qX",
name:"Furibee 40a",
type:"esc"
}}}},
{
data() { return { specs: {
count:4,
forSale:false,
group:"qPELnTnwGJEtJexgP2qX",
name:"Runcam Cam 1",
type:"camera"
}}}},
{
data() { return { specs: {
count:1,
forSale:false,
group:"qPELnTnwGJEtJexgP2qX",
name:"Hobbywing 4 in 1",
type:"esc"
}}}}
];
const typeObj = results.reduce((a, item) => {
const { count, type } = item.data().specs;
if (!a[type]) a[type] = { count: 0 };
a[type].count += count;
return a;
}, {});
console.log(typeObj);
Upvotes: 1
Reputation: 57954
You can use Array#reduce
to accomplish this since you want to transform an array into a single object:
const array = [
{
id: 'uniqueID',
specs: {
count: 5,
forSale: false,
group: "qPELnTnwGJEtJexgP2qX",
name: "Foxeer Cam 2",
type: "camera"
}
},
{
id: 'uniqueID',
specs: {
count: 4,
forSale: false,
group: "qPELnTnwGJEtJexgP2qX",
name: "Furibee 40a",
type: "esc"
}
},
{
id: 'uniqueID',
specs: {
count: 4,
forSale: false,
group: "qPELnTnwGJEtJexgP2qX",
name: "Runcam Cam 1",
type: "camera"
}
},
{
id: 'uniqueID',
specs: {
count: 1,
forSale: false,
group: "qPELnTnwGJEtJexgP2qX",
name: "Hobbywing 4 in 1",
type: "esc"
}
}
];
const typeObj = array.reduce((obj, { specs: { count, type } }) => {
obj[type] = obj[type] || { count: 0 };
obj[type].count += count;
return obj;
}, {});
console.log(typeObj);
What this does is assign obj[type]
to either itself or if it doesn't yet exist, a new object { count: 0 }
. Then it increments the count
property of obj[type]
by the specified count in the data.
If you have a data
method that returns an object with the data (as you seem to have in the question), you can modify it like so:
const typeObj = array.reduce((obj, item) => {
const { type, count } = item.data().specs;
obj[type] = obj[type] || { count: 0 };
obj[type].count += count;
return obj;
}, {});
console.log(typeObj);
Upvotes: 2