javascriptreactjsreduxreducereact-redux-form

How do I group objects by key and modify the array the reduce function returns?


I use Redux to store all my products in a list. Displayed thist list looks like:

[
  {
    "id": 1,
    "name": "BLACK TEA",
    "supplieruuid": "SLIGRO",
  },
  {
    "id": 2,
    "name": "GREEN TEA",
    "supplieruuid": "SLIGRO",
  },
  {
    "id": 3,
    "name": "PURPLE TEA",
    "supplieruuid": "BUNZL",
  },
  {
    "id": 4,
    "name": "RAINBOW TEA",
    "supplieruuid": "BUNZL",
  },
] 

I'm using this reduce function to group these products together by key supplieruuid.

export const selectSortedItems = (state) => state.entities.cart.list.reduce((hash, { ["supplieruuid"]: value, ...rest }) => ({ ...hash, [value]: (hash[value] || []).concat({ ...rest }) }), {});

This returns this array of the products grouped by the key supplieruuid.

[
    {
        "SLIGRO": [
        {
            "id": 1,
            "name": "BLACK TEA",
            "supplieruuid": "SLIGRO",
        },
        {
            "id": 2,
            "name": "GREEN TEA",
            "supplieruuid": "SLIGRO",
        },
        ],
        "BUNZL": [
        {
            "id": 3,
            "name": "PURPLE TEA",
            "supplieruuid": "BUNZL",
        },
        {
            "id": 4,
            "name": "RAINBOW TEA",
            "supplieruuid": "BUNZL",
        },
        ],
    },
] 

except I need this returned as following:

 [
    {
        title: "SLIGRO",
        data: [
        {
            "id": 1,
            "name": "BLACK TEA",
        },
        {
            "id": 2,
            "name": "GREEN TEA",
        },
        ],
    },
    {
        title: "BUNZL",
        data: [
        {
            "id": 3,
            "name": "PURPLE TEA",
        },
        {
            "id": 4,
            "name": "RAINBOW TEA",
        },
        ],
    },
] 

How can I modify the reduce function to display the array as above? With the title and data added.


Solution

  • You could take a grouping with an object and a destructuring with unwanted properties for the data. At the end take only the values from the object.

    const
        data = [{ id: 1, name: "BLACK TEA", supplieruuid: "SLIGRO" }, { id: 2, name: "GREEN TEA", supplieruuid: "SLIGRO" }, { id: 3, name: "PURPLE TEA", supplieruuid: "BUNZL" }, { id: 4, name: "RAINBOW TEA", supplieruuid: "BUNZL" }],
        result = Object.values(data.reduce((r, { supplieruuid: title, ...o }) => {
            (r[title] ??= { title, data: [] }).data.push(o);
            return r;
        }, {}));
    
    console.log(result);
    .as-console-wrapper { max-height: 100% !important; top: 0; }