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?

bonnegnu
  • 175
  • 3
  • 12
  • 1
    what the output you want to get in the end? – zb22 Dec 13 '20 at 20:35
  • I inserted the table in Markdown format so you can see the result I want – bonnegnu Dec 13 '20 at 20:43
  • Please see this post. It has almost same question. https://stackoverflow.com/a/34890276/9515661 – Alexey Victorov Dec 13 '20 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'));` – bonnegnu Dec 13 '20 at 21:56

2 Answers2

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

CeamKrier
  • 629
  • 7
  • 15
  • 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. – bonnegnu Dec 13 '20 at 21:30
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);
zb22
  • 3,126
  • 3
  • 19
  • 34