[Vuejs]-How to groupBy and iterate on object/array with a .reduce in Vue?

1👍

You could use this reducer with the following function

function groupBy(objectArray, property) {
  return objectArray.reduce((acc, obj) => {
    const key = obj[property];
    const curGroup = acc[key] ?? [];

    return { ...acc, [key]: [...curGroup, obj] };
  }, {});
}

This would give us this well formatted object to then iterate on

const t = [
  { id: 11, item: "first one" },
  { id: 49, item: "tasty thing" },
  { id: 11, item: "amazing right?" },
  { id: 20, item: "cool cool" },
  { id: 49, item: "love watermelons" },
  { id: 83, item: "and you?" },
]

groupBy(t, 'id')
// this will give us the following
{
  "11": [
    {
      "id": 11,
      "item": "first one"
    },
    {
      "id": 11,
      "item": "amazing right?"
    }
  ],
  "20": [
    {
      "id": 20,
      "item": "cool cool"
    }
  ],
  "49": [
    {
      "id": 49,
      "item": "tasty thing"
    },
    {
      "id": 49,
      "item": "love watermelons"
    }
  ],
  "83": [
    {
      "id": 83,
      "item": "and you?"
    }
  ]
}

The whole could would look like this

<template>
  <main>
    <div v-for="(groupedArray, id) in objectToLoopOn" :key="id">
      <pre v-for="array in groupedArray" :key="array.item">{{ array }}</pre>
      <hr />
    </div>
  </main>
</template>

<script>
const groupBy = (objectArray, property) => {
  return objectArray.reduce((acc, obj) => {
    const key = obj[property];
    const curGroup = acc[key] ?? [];

    return { ...acc, [key]: [...curGroup, obj] };
  }, {});
};

export default {
  data() {
    return {
      objectToLoopOn: groupBy(
        [
          { id: 11, item: "first one" },
          { id: 49, item: "tasty thing" },
          { id: 11, item: "amazing right?" },
          { id: 20, item: "cool cool" },
          { id: 49, item: "love watermelons" },
          { id: 83, item: "and you?" },
        ],
        "id"
      ),
    };
  },
};
</script>

Providing us this kind of visual result

enter image description here

👤kissu

Leave a comment