Pankaj Nikam
Pankaj Nikam

Reputation: 107

How to group an array of objects based on multiple keys in Javascript?

I have array as follows

 [
  {
    "WarehouseId": 1,
    "ShippingCarrierId": 1,
    "PostalCodeType": "ShipToCustomer",
    "TimeStart": "1970-01-01T06:00:00.000Z",
    "TimeEnd": "1970-01-01T15:59:00.000Z",
    "PickupTimeSlot": "PM",
    "DaysToAdd": 0,
    "PickupTime": "1970-01-01T17:00:00.000Z"
  },
  {
    "WarehouseId": 1,
    "ShippingCarrierId": 1,
    "PostalCodeType": "ShipToCustomer",
    "TimeStart": "1970-01-01T16:00:00.000Z",
    "TimeEnd": "1970-01-01T23:59:00.000Z",
    "PickupTimeSlot": "AM",
    "DaysToAdd": 1,
    "PickupTime": "1970-01-01T11:00:00.000Z"
  },
  {
    "WarehouseId": 1,
    "ShippingCarrierId": 1,
    "PostalCodeType": "ShipToCustomer",
    "TimeStart": "1970-01-01T00:00:00.000Z",
    "TimeEnd": "1970-01-01T05:59:00.000Z",
    "PickupTimeSlot": "AM",
    "DaysToAdd": 0,
    "PickupTime": "1970-01-01T11:00:00.000Z"
  },
  {
    "WarehouseId": 2,
    "ShippingCarrierId": 2,
    "PostalCodeType": "ShipToCustomer",
    "TimeStart": "1970-01-01T00:00:00.000Z",
    "TimeEnd": "1970-01-01T15:59:00.000Z",
    "PickupTimeSlot": "PM",
    "DaysToAdd": 0,
    "PickupTime": "1970-01-01T17:00:00.000Z"
  },
  {
    "WarehouseId": 2,
    "ShippingCarrierId": 2,
    "PostalCodeType": "ShipToCustomer",
    "TimeStart": "1970-01-01T16:00:00.000Z",
    "TimeEnd": "1970-01-01T23:59:00.000Z",
    "PickupTimeSlot": "AM",
    "DaysToAdd": 1,
    "PickupTime": "1970-01-01T11:00:00.000Z"
  },
  {
    "WarehouseId": 1,
    "ShippingCarrierId": 3,
    "PostalCodeType": "ShipToDS",
    "TimeStart": "1970-01-01T00:00:00.000Z",
    "TimeEnd": "1970-01-01T15:59:00.000Z",
    "PickupTimeSlot": "PM",
    "DaysToAdd": 0,
    "PickupTime": "1970-01-01T17:00:00.000Z"
  },
  {
    "WarehouseId": 1,
    "ShippingCarrierId": 3,
    "PostalCodeType": "ShipToDS",
    "TimeStart": "1970-01-01T16:00:00.000Z",
    "TimeEnd": "1970-01-01T23:59:00.000Z",
    "PickupTimeSlot": "AM",
    "DaysToAdd": 1,
    "PickupTime": "1970-01-01T11:00:00.000Z"
  },
  {
    "WarehouseId": 2,
    "ShippingCarrierId": 4,
    "PostalCodeType": "ShipToDS",
    "TimeStart": "1970-01-01T00:00:00.000Z",
    "TimeEnd": "1970-01-01T15:59:00.000Z",
    "PickupTimeSlot": "PM",
    "DaysToAdd": 0,
    "PickupTime": "1970-01-01T17:00:00.000Z"
  },
  {
    "WarehouseId": 2,
    "ShippingCarrierId": 4,
    "PostalCodeType": "ShipToDS",
    "TimeStart": "1970-01-01T16:00:00.000Z",
    "TimeEnd": "1970-01-01T23:59:00.000Z",
    "PickupTimeSlot": "AM",
    "DaysToAdd": 1,
    "PickupTime": "1970-01-01T11:00:00.000Z"
  },
  {
    "WarehouseId": 1,
    "ShippingCarrierId": 5,
    "PostalCodeType": "ShipToDS",
    "TimeStart": "1970-01-01T00:00:00.000Z",
    "TimeEnd": "1970-01-01T16:22:00.000Z",
    "PickupTimeSlot": "PM",
    "DaysToAdd": 0,
    "PickupTime": "1970-01-01T17:00:00.000Z"
  },
  {
    "WarehouseId": 1,
    "ShippingCarrierId": 5,
    "PostalCodeType": "ShipToDS",
    "TimeStart": "1970-01-01T16:23:00.000Z",
    "TimeEnd": "1970-01-01T23:59:00.000Z",
    "PickupTimeSlot": "AM",
    "DaysToAdd": 1,
    "PickupTime": "1970-01-01T11:00:00.000Z"
  },
  {
    "WarehouseId": 2,
    "ShippingCarrierId": 6,
    "PostalCodeType": "ShipToDS",
    "TimeStart": "1970-01-01T00:00:00.000Z",
    "TimeEnd": "1970-01-01T15:59:00.000Z",
    "PickupTimeSlot": "PM",
    "DaysToAdd": 0,
    "PickupTime": "1970-01-01T17:00:00.000Z"
  },
  {
    "WarehouseId": 2,
    "ShippingCarrierId": 6,
    "PostalCodeType": "ShipToDS",
    "TimeStart": "1970-01-01T16:00:00.000Z",
    "TimeEnd": "1970-01-01T23:59:00.000Z",
    "PickupTimeSlot": "AM",
    "DaysToAdd": 1,
    "PickupTime": "1970-01-01T11:00:00.000Z"
  },
  {
    "WarehouseId": 1,
    "ShippingCarrierId": 1,
    "PostalCodeType": "ShipToDS",
    "TimeStart": "1970-01-01T06:00:00.000Z",
    "TimeEnd": "1970-01-01T15:59:00.000Z",
    "PickupTimeSlot": "PM",
    "DaysToAdd": 0,
    "PickupTime": "1970-01-01T17:00:00.000Z"
  },
  {
    "WarehouseId": 1,
    "ShippingCarrierId": 1,
    "PostalCodeType": "ShipToDS",
    "TimeStart": "1970-01-01T16:00:00.000Z",
    "TimeEnd": "1970-01-01T23:59:00.000Z",
    "PickupTimeSlot": "AM",
    "DaysToAdd": 1,
    "PickupTime": "1970-01-01T11:00:00.000Z"
  },
  {
    "WarehouseId": 1,
    "ShippingCarrierId": 1,
    "PostalCodeType": "ShipToDS",
    "TimeStart": "1970-01-01T00:00:00.000Z",
    "TimeEnd": "1970-01-01T05:59:00.000Z",
    "PickupTimeSlot": "AM",
    "DaysToAdd": 0,
    "PickupTime": "1970-01-01T11:00:00.000Z"
  },
  {
    "WarehouseId": 2,
    "ShippingCarrierId": 2,
    "PostalCodeType": "ShipToDS",
    "TimeStart": "1970-01-01T00:00:00.000Z",
    "TimeEnd": "1970-01-01T15:59:00.000Z",
    "PickupTimeSlot": "PM",
    "DaysToAdd": 0,
    "PickupTime": "1970-01-01T17:00:00.000Z"
  },
  {
    "WarehouseId": 2,
    "ShippingCarrierId": 2,
    "PostalCodeType": "ShipToDS",
    "TimeStart": "1970-01-01T16:00:00.000Z",
    "TimeEnd": "1970-01-01T23:59:00.000Z",
    "PickupTimeSlot": "AM",
    "DaysToAdd": 1,
    "PickupTime": "1970-01-01T11:00:00.000Z"
  }
]

I want to group it by WarehouseId, ShippingCarrierId and PostalCodeType. Each objec will have chlid array of objects for Timestart, TimeEnd etc

How can I achieve this

output like :

PickupTimeTable: [{
            WarehouseId: 1,
            ShippingCarrierId: 1,
            PostalCodeType: 'ShipToCustomer',
            PickupTimeSlots: [{
                    StartTime: '06:00:00.0000000',
                    EndTime: '15:59:00.0000000',
                    Slot: 'PM',
                    PickupTime: '17:00:00.0000000',
                    DaysToAdd: 0
                },
                {
                    StartTime: '16:00:00.0000000',
                    EndTime: '23:59:00.0000000',
                    Slot: 'AM',
                    PickupTime: '11:00:00.0000000',
                    DaysToAdd: 1
                },
                {
                    StartTime: '00:00:00.0000000',
                    EndTime: '05:59:00.0000000',
                    Slot: 'AM',
                    PickupTime: '11:00:00.0000000',
                    DaysToAdd: 0
                },
            ]
        }, ]

Upvotes: 5

Views: 10808

Answers (3)

adiga
adiga

Reputation: 35263

You could create an accumulator object with a new key for each unique combination of those 3 keys seperated by -. Then based on this new key merge the array using reduce. Use destructuring to separate the keys you need in the PickupTimeSlots to a rest variable. Then use Object.values to get the final array:

const slots=[{"WarehouseId":1,"ShippingCarrierId":1,"PostalCodeType":"ShipToCustomer","TimeStart":"1970-01-01T06:00:00.000Z","TimeEnd":"1970-01-01T15:59:00.000Z","PickupTimeSlot":"PM","DaysToAdd":0,"PickupTime":"1970-01-01T17:00:00.000Z"},{"WarehouseId":1,"ShippingCarrierId":1,"PostalCodeType":"ShipToCustomer","TimeStart":"1970-01-01T16:00:00.000Z","TimeEnd":"1970-01-01T23:59:00.000Z","PickupTimeSlot":"AM","DaysToAdd":1,"PickupTime":"1970-01-01T11:00:00.000Z"},{"WarehouseId":1,"ShippingCarrierId":1,"PostalCodeType":"ShipToCustomer","TimeStart":"1970-01-01T00:00:00.000Z","TimeEnd":"1970-01-01T05:59:00.000Z","PickupTimeSlot":"AM","DaysToAdd":0,"PickupTime":"1970-01-01T11:00:00.000Z"},{"WarehouseId":2,"ShippingCarrierId":2,"PostalCodeType":"ShipToCustomer","TimeStart":"1970-01-01T00:00:00.000Z","TimeEnd":"1970-01-01T15:59:00.000Z","PickupTimeSlot":"PM","DaysToAdd":0,"PickupTime":"1970-01-01T17:00:00.000Z"},{"WarehouseId":2,"ShippingCarrierId":2,"PostalCodeType":"ShipToCustomer","TimeStart":"1970-01-01T16:00:00.000Z","TimeEnd":"1970-01-01T23:59:00.000Z","PickupTimeSlot":"AM","DaysToAdd":1,"PickupTime":"1970-01-01T11:00:00.000Z"},{"WarehouseId":1,"ShippingCarrierId":3,"PostalCodeType":"ShipToDS","TimeStart":"1970-01-01T00:00:00.000Z","TimeEnd":"1970-01-01T15:59:00.000Z","PickupTimeSlot":"PM","DaysToAdd":0,"PickupTime":"1970-01-01T17:00:00.000Z"},{"WarehouseId":1,"ShippingCarrierId":3,"PostalCodeType":"ShipToDS","TimeStart":"1970-01-01T16:00:00.000Z","TimeEnd":"1970-01-01T23:59:00.000Z","PickupTimeSlot":"AM","DaysToAdd":1,"PickupTime":"1970-01-01T11:00:00.000Z"},{"WarehouseId":2,"ShippingCarrierId":4,"PostalCodeType":"ShipToDS","TimeStart":"1970-01-01T00:00:00.000Z","TimeEnd":"1970-01-01T15:59:00.000Z","PickupTimeSlot":"PM","DaysToAdd":0,"PickupTime":"1970-01-01T17:00:00.000Z"},{"WarehouseId":2,"ShippingCarrierId":4,"PostalCodeType":"ShipToDS","TimeStart":"1970-01-01T16:00:00.000Z","TimeEnd":"1970-01-01T23:59:00.000Z","PickupTimeSlot":"AM","DaysToAdd":1,"PickupTime":"1970-01-01T11:00:00.000Z"},{"WarehouseId":1,"ShippingCarrierId":5,"PostalCodeType":"ShipToDS","TimeStart":"1970-01-01T00:00:00.000Z","TimeEnd":"1970-01-01T16:22:00.000Z","PickupTimeSlot":"PM","DaysToAdd":0,"PickupTime":"1970-01-01T17:00:00.000Z"},{"WarehouseId":1,"ShippingCarrierId":5,"PostalCodeType":"ShipToDS","TimeStart":"1970-01-01T16:23:00.000Z","TimeEnd":"1970-01-01T23:59:00.000Z","PickupTimeSlot":"AM","DaysToAdd":1,"PickupTime":"1970-01-01T11:00:00.000Z"},{"WarehouseId":2,"ShippingCarrierId":6,"PostalCodeType":"ShipToDS","TimeStart":"1970-01-01T00:00:00.000Z","TimeEnd":"1970-01-01T15:59:00.000Z","PickupTimeSlot":"PM","DaysToAdd":0,"PickupTime":"1970-01-01T17:00:00.000Z"},{"WarehouseId":2,"ShippingCarrierId":6,"PostalCodeType":"ShipToDS","TimeStart":"1970-01-01T16:00:00.000Z","TimeEnd":"1970-01-01T23:59:00.000Z","PickupTimeSlot":"AM","DaysToAdd":1,"PickupTime":"1970-01-01T11:00:00.000Z"},{"WarehouseId":1,"ShippingCarrierId":1,"PostalCodeType":"ShipToDS","TimeStart":"1970-01-01T06:00:00.000Z","TimeEnd":"1970-01-01T15:59:00.000Z","PickupTimeSlot":"PM","DaysToAdd":0,"PickupTime":"1970-01-01T17:00:00.000Z"},{"WarehouseId":1,"ShippingCarrierId":1,"PostalCodeType":"ShipToDS","TimeStart":"1970-01-01T16:00:00.000Z","TimeEnd":"1970-01-01T23:59:00.000Z","PickupTimeSlot":"AM","DaysToAdd":1,"PickupTime":"1970-01-01T11:00:00.000Z"},{"WarehouseId":1,"ShippingCarrierId":1,"PostalCodeType":"ShipToDS","TimeStart":"1970-01-01T00:00:00.000Z","TimeEnd":"1970-01-01T05:59:00.000Z","PickupTimeSlot":"AM","DaysToAdd":0,"PickupTime":"1970-01-01T11:00:00.000Z"},{"WarehouseId":2,"ShippingCarrierId":2,"PostalCodeType":"ShipToDS","TimeStart":"1970-01-01T00:00:00.000Z","TimeEnd":"1970-01-01T15:59:00.000Z","PickupTimeSlot":"PM","DaysToAdd":0,"PickupTime":"1970-01-01T17:00:00.000Z"},{"WarehouseId":2,"ShippingCarrierId":2,"PostalCodeType":"ShipToDS","TimeStart":"1970-01-01T16:00:00.000Z","TimeEnd":"1970-01-01T23:59:00.000Z","PickupTimeSlot":"AM","DaysToAdd":1,"PickupTime":"1970-01-01T11:00:00.000Z"}]

const merged = slots.reduce((r, { WarehouseId, ShippingCarrierId, PostalCodeType,...rest }) => {
  const key = `${WarehouseId}-${ShippingCarrierId}-${PostalCodeType}`;
  r[key] = r[key] || { WarehouseId, ShippingCarrierId, PostalCodeType, PickupTimeSlots: [] };
  r[key]["PickupTimeSlots"].push(rest)
  return r;
}, {})

const timeTable = Object.values(merged)
console.log(timeTable)

Upvotes: 13

Roopak A Nelliat
Roopak A Nelliat

Reputation: 2551

You can use groupBy function from lodash - https://lodash.com/docs/4.17.11#groupBy

let groupBy = _.groupBy(array, 'WarehouseId');

Gives you ->

wareHouseId1: [...], 
wareHouseId2: [...]

Multi-level grouping is not supported by library.

Upvotes: 1

TLbiz
TLbiz

Reputation: 497

You can use reduce to solve this problem

let groupBy = function(array, key) {
  return array.reduce(function(result, item) {
    (result[item[key]] = result[item[key]] || []).push(item);
    return result;
  }, {});
};

console.log(groupBy(yourarray, 'yourkey'));

Upvotes: 0

Related Questions