0

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?

asked Dec 13, 2020 at 20:32
4
  • 1
    what the output you want to get in the end? Commented Dec 13, 2020 at 20:35
  • I inserted the table in Markdown format so you can see the result I want Commented Dec 13, 2020 at 20:43
  • Please see this post. It has almost same question. stackoverflow.com/a/34890276/9515661 Commented Dec 13, 2020 at 20:49
  • Tried the following, but it doesn't group: 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')); Commented Dec 13, 2020 at 21:56

2 Answers 2

1

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
Sign up to request clarification or add additional context in comments.

3 Comments

Thank you! I'll test it by creating the table and then I'll tell you how it turned out.
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?
@bonnegnu map() is fine
1

You 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

1 Comment

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.

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.