1

I have an array of objects like this

[
 { id: 1, note: "TEST", member_id: 1, updated_at: "2021-04-08T15:59:08.210754", product_id: 1,
 product: { id: 1, name: "Testing",},},
 {id: 2, note: "", member_id: 1, updated_at: "2021-04-08T18:07:19.712304", product_id: 5,
 product: { id: 5, name: "Insurance"}, },
 { id: 3, note: "One note", member_id: 1, updated_at: "2021-04-08T18:11:26.444726", product_id: 5, 
 product: { id: 5, name: "Insurance" },},
{ id: 4, note: "sadad", member_id: 1, updated_at: "2021-04-08T18:28:59.8435", product_id: 5, product: 
 { id: 5, name: "Insurance" }, },
];

I have to represent it in a table where it can be grouped by product name and the number of objects that have the same product is counted as well as the last update of any of them is shown.

It should look like this enter image description here

Try to use reduce but I could not advance much because I did not understand it and I used grouby with lodash but I could not advance more than that

I need it to stay like this

[
 {product: "Insurance", 
 quantity: 3, 
 updated_at: "2021-04-08", 
 sales: [ 
         { id: 2, 
           note: "", 
           member_id: 1, 
           updated_at: "2021-04-08", 
           product_id: 5
         }, 
         { id: 3, 
           note: "One note", 
           member_id: 1, 
           updated_at: "2021-04-08", 
           product_id: 5
         }, 
         { id: 4, 
           note: "sadad", 
           member_id: 1, 
           updated_at: "2021-04-08",
           product_id: 5
         }
        ]
  },
  {product: "Testing", 
   quantity: 1, 
   updated_at: "2021-04-08", 
   sales: [ 
           {id: 1, 
            note: "TEST", 
            member_id: 1, 
            updated_at: "2021-04-08", 
            product_id: 1,} 
          ]},
]

I tried to use reduce but it was not what I expected and I did not understand it much either

array.reduce((acc, it) => {
acc[it.product.name] = acc[it.product.name] + 1 || 1;
return acc;
}, {});
  • Maybe this will be of help to you. https://stackoverflow.com/questions/40774697/how-to-group-an-array-of-objects-by-key – RGA Apr 12 '21 at 13:43
  • you haven't shown any attempt, please provide it. Aslo please provide the final JSON structure you want – EugenSunic Apr 12 '21 at 13:48
  • I already completed the missing data, could you guide me how to solve the problem? @EugenSunic – Jorge Barcos Apr 12 '21 at 14:17
  • Does this answer your question? [Most efficient method to groupby on an array of objects](https://stackoverflow.com/questions/14446511/most-efficient-method-to-groupby-on-an-array-of-objects) – pilchard Apr 12 '21 at 14:20

3 Answers3

2
const sales = [
  {
    "id": 1,
    "note": "TEST",
    "member_id": 1,
    "updated_at": "2021-04-08T15:59:08.210754",
    "product_id": 1,
    "product": {
      "id": 1,
      "name": "Testing"
    }
  },
  {
    "id": 2,
    "note": "",
    "member_id": 1,
    "updated_at": "2021-04-08T18:07:19.712304",
    "product_id": 5,
    "product": {
      "id": 5,
      "name": "Insurance"
    }
  },
  {
    "id": 3,
    "note": "One note",
    "member_id": 1,
    "updated_at": "2021-04-08T18:11:26.444726",
    "product_id": 5,
    "product": {
      "id": 5,
      "name": "Insurance"
    }
  },
  {
    "id": 4,
    "note": "sadad",
    "member_id": 1,
    "updated_at": "2021-04-08T18:28:59.8435",
    "product_id": 5,
    "product": {
      "id": 5,
      "name": "Insurance"
    }
  }
];


const newObject = sales.reduce((allProducts, singleSale) => {
  if(allProducts.has(singleSale.product.name)){

    const product = allProducts.get(singleSale.product.name);
    
    allProducts.set(singleSale.product.name, {
      ...product,
      quantity: product.sales.length + 1,
      sales: [...product.sales, singleSale]
    });

  } else {
    allProducts.set(singleSale.product.name, {
      product: singleSale.product.name,
      quantity: 1, 
      sales: [singleSale]
    })
  }
  
  return allProducts;
}, new Map());

console.log([...newObject.values()])

https://jsbin.com/govocoyeri/edit?js,console

This should give you the desired result.

N.K.
  • 464
  • 2
  • 4
1

You can try something like this, it will should give you the desired output.

const list = [{
    id: 1,
    note: "TEST",
    member_id: 1,
    updated_at: "2021-04-08T15:59:08.210754",
    product_id: 1,
    product: {
      id: 1,
      name: "Testing",
    },
  },
  {
    id: 2,
    note: "",
    member_id: 1,
    updated_at: "2021-04-08T18:07:19.712304",
    product_id: 5,
    product: {
      id: 5,
      name: "Insurance"
    },
  },
  {
    id: 3,
    note: "One note",
    member_id: 1,
    updated_at: "2021-04-08T18:11:26.444726",
    product_id: 5,
    product: {
      id: 5,
      name: "Insurance"
    },
  },
  {
    id: 4,
    note: "sadad",
    member_id: 1,
    updated_at: "2021-04-08T18:28:59.8435",
    product_id: 5,
    product: {
      id: 5,
      name: "Insurance"
    },
  },
];

const result = list.reduce((acc, x) => {
  const index = acc.findIndex(obj => obj.product === x.product.name);
  const salesObj = {
    id: x.id,
    note: x.note,
    member_id: x.member_id,
    updated_at: x.updated_at,
    product_id: x.product_id
  };
  if (index < 0) {
    acc = [...acc, {
      product: x.product.name,
      quantity: 1,
      updated_at: x.updated_at,
      sales: [salesObj]
    }];
    return acc;
  }
  acc[index].updated_at = x.updated_at;
  acc[index].quantity++;
  acc[index].sales.push(salesObj);
  return acc;
}, []);

console.log(result)
EugenSunic
  • 13,162
  • 13
  • 64
  • 86
1

Use _.gropyBy to group the items, and use _.toPairs to get key-value pair of an object and then use map to customize the objects in a group

here list is the input array

var result = _.toPairs(_.groupBy(list, 'product.name'))
 .map(([product, sales]) => {
    const quantity = sales.length;
        return {
            product, 
            quantity, 
            updated_at: sales[quantity-1].updated_at, 
            sales: sales.map(item => _.omit(item, 'product')) 
        }
    });
console.log(result)
Punith Mithra
  • 608
  • 5
  • 9