I have a question, how can I map and reduce an array like this:
[
{
id: 1,
Price: 50,
Item: {id: 1, Name: "A"},
Date: {id: 1, Start: "202001"}
},
{
id: 2,
Price: 100,
Item: {id: 1, Name: "A"},
Date: {id: 2, Start: "202002"}
},
{
id: 3,
Price: 200,
Item: {id: 2, Name: "B"},
Date: {id: 1, Start: "202001"}
}
]
I'm writing an app in React and I want to show those values grouped in a table.
It should look something like this:
| ITEM | 202001 | 202002 |
|---|---|---|
| A | 50 | 100 |
| B | - | 200 |
I would like to be able to do this with the array:
[
{
id: 1,
Item: {id: 1, Name: "A"},
Date: [{id: 1, Start: "202001",Price: "50"},{id: 2, Start: "202002",Price: "100"}]
},
{
id: 2,
Item: {id: 2, Name: "B"},
Date: {id: 1, Start: "202001",Price: "200"}
}
]
Any suggestions to get to what I need?
2 Answers 2
You can use Array.prototype.reduce() and then use Object.values like so:
const arr = [
{
id: 1,
Price: 50,
Item: {id: 1, Name: "A"},
Date: {id: 1, Start: "202001"}
},
{
id: 2,
Price: 100,
Item: {id: 1, Name: "A"},
Date: {id: 2, Start: "202002"}
},
{
id: 3,
Price: 200,
Item: {id: 2, Name: "B"},
Date: {id: 1, Start: "202001"}
}
]
const res = Object.values(arr.reduce((acc, {Item, Date, Price}) => {
if(!acc[Item.id]) {
acc[Item.id] = {
id: Item.id,
Item,
Date: [{...Date, Price}]
};
} else {
acc[Item.id].Date = [...acc[Item.id].Date, {...Date, Price}];
}
return acc;
}, {}));
console.log(res);
answered Dec 13, 2020 at 22:26
zb22
3,2413 gold badges22 silver badges38 bronze badges
Sign up to request clarification or add additional context in comments.
3 Comments
bonnegnu
Thank you! I'll test it by creating the table and then I'll tell you how it turned out.
bonnegnu
I wanted to order the array this way, to map the data easier. What is the best way to loop through it and display the values as they are in the table?
zb22
@bonnegnu
map() is fineYou can use groupBy method of lodash to group your dataset according to Item.Name.
First get the package:
npm i lodash.groupby
Then use it in your code as
import groupBy from 'lodash.groupby'
const tempData = [
{
id: 1,
Price: 50,
Item: {id: 1, Name: "A"},
Date: {id: 1, Start: "202001"}
},
{
id: 2,
Price: 100,
Item: {id: 1, Name: "A"},
Date: {id: 2, Start: "202002"}
},
{
id: 3,
Price: 200,
Item: {id: 2, Name: "B"},
Date: {id: 1, Start: "202001"}
}
]
groupBy(tempData, 'Item.Name')
/*
Will result as below
{
A: [
//objects with 'Item.Name' === 'A'
],
B: [
//objects with 'Item.Name' === 'B'
]
}
*/
Then, you need to populate your table with the keys inside the response from groupBy
answered Dec 13, 2020 at 20:50
CeamKrier
93911 silver badges18 bronze badges
1 Comment
bonnegnu
Thanks for the help. I get this error ./node_modules/lodash.groupby/index.js - Module not found after installing lodash.groupby and running the app.
lang-js
const tempData = [ { id: 1, Price: 50, Item: {id: 1, Name: "A"}, Date: {id: 1, Start: "202001"} }, { id: 2, Price: 100, Item: {id: 1, Name: "A"}, Date: {id: 2, Start: "202002"} }, { id: 3, Price: 200, Item: {id: 2, Name: "B"}, Date: {id: 1, Start: "202001"} } ] var groupBy = function(xs, key) { return xs.reduce(function(rv, x) { (rv[x[key]] = rv[x[key]] || []).push(x); return rv; }, {}); }; console.log(groupBy(tempData, 'Item.Name'));