'Create an array of objects based on property from other array of objects

I have a plain array of objects that I need to convert into a new specified array of objects, based on time. The similar time data should be in the same object. For example:

I have an array of objects like this:

[
    {
        "id": 11,
        "roomId": 1,
        "startTime": "9",
        "name" : "xyz"
    },
    {
        "id": 12,
        "roomId": 2,
        "startTime": "9",
        "name" : "xyz2"
    },
    {
        "id": 13,
        "roomId": 3,
        "startTime": "10",
        "name" : "xyz3"
    },
    {
        "id": 14,
        "roomId": 1,
        "startTime": "9",
        "name" : "xyz4"
    }
]

The end result should be :

[
  {
    time: "9",
    blocks: {
      "1": [{
        name: 'xyz'
      }, 
      {
        name: 'xyz4'
      }],
      "2": [{
        name: 'xyz2'
      }]
    }
  },
  {
    time: "10",
    blocks: {
      "3": [{
        name: 'xyz3'
      }]
    }
  }
]


Solution 1:[1]

  • Using Array#reduce, iterate over the array while updating a Map where the startTime is the key and the corresponding grouped object is the value
  • In every iteration, get the current record for the time if exists. Then, update the blocks object. Finally, update the map with the new details.
  • Using Map#values, get the list of grouped objects by time

const arr = [ { "id": 11, "roomId": 1, "startTime": "9", "name" : "xyz" }, { "id": 12, "roomId": 2, "startTime": "9", "name" : "xyz2" }, { "id": 13, "roomId": 3, "startTime": "10", "name" : "xyz3" }, { "id": 14, "roomId": 1, "startTime": "9", "name" : "xyz4" } ];

const res = [...
  arr.reduce((map, { id, roomId, startTime, name }) => {
    const current = map.get(startTime) ?? { time: startTime, blocks: {} };
    current.blocks[roomId] = [ ...(current.blocks[roomId] ?? []), { name } ];
    map.set(startTime, current);
    return map;
  }, new Map)
  .values()
];

console.log(res);

Solution 2:[2]

You can Array.prototype.reduce() combined with Destructuring assignment, Spread syntax and get the result values with Object.values()

Code:

const data = [{ id: 11, roomId: 1, startTime: '9', name: 'xyz' },{ id: 12, roomId: 2, startTime: '9', name: 'xyz2' },{ id: 13, roomId: 3, startTime: '10', name: 'xyz3' },{ id: 14, roomId: 1, startTime: '9', name: 'xyz4' }]

const dataHash = data.reduce((a, { startTime: st, roomId, name }) => {
  a[st] = a[st] || { time: st, blocks: {} }
  a[st].blocks[roomId] = [...(a[st].blocks[roomId] || []), { name }]
  return a
}, {})

const result = Object.values(dataHash)

console.log(result)

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Majed Badawi
Solution 2