1

I have an input:

var modbusData = [
  { Type: "rtu", Mode: "master", IdDevice: "1", Time: "11:01:00", Data: "1,12,23" },
  { Type: "tcp", Mode: "client", IdDevice: "2", Time: "11:01:11", Data: "30,40,50" },
  { Type: "rtu", Mode: "slave", IdDevice: "1", Time: "11:02:00", Data: "5,10,21" },
  { Type: "tcp", Mode: "server", IdDevice: "2", Time: "11:02:11", Data: "32,44,53" },
];

After I call a funciton for grouping input following Type:

function groupBy(objectArray, property, expectedGroups = []) {
  return objectArray.reduce(function (acc, obj) {
    let key = obj[property]
    if (!acc[key]) {
      acc[key] = []
    }
    acc[key].push(obj)
    return acc
  }, Object.fromEntries(expectedGroups.map(k => [k, []])))
};
const groupedData = groupBy(modbusData, 'Type', [ 'rtu', 'tcp' ]);
console.log(groupedData);

The result will be:

{
  rtu: [
    { Type: 'rtu', Mode: 'master', IdDevice: '1', Time: '11:01:00', Data: '1,12,23' },
    { Type: 'rtu', Mode: 'slave', IdDevice: '1', Time: '11:02:00', Data: '5,10,21' }
  ],
  tcp: [
    { Type: 'tcp', Mode: 'client', IdDevice: '2', Time: '11:01:11', Data: '30,40,50' },
    { Type: 'tcp', Mode: 'server', IdDevice: '2', Time: '11:02:11', Data: '32,44,53' }
  ]
}

And now I want a duplicate GroupBy with Mode, especially when Any Mode is not exist, they will return empty array, which result would be:

{
  rtu: {
    master: [{ Type: 'rtu', Mode: 'master', IdDevice: '1', Time: '11:01:00', Data: '1,12,23' }],
    slave: [{ Type: 'rtu', Mode: 'slave', IdDevice: '1', Time: '11:02:00', Data: '5,10,21' }]
  },
  tcp: {
    client: [{ Type: 'tcp', Mode: 'client', IdDevice: '2', Time: '11:01:11', Data: '30,40,50' }],
    server: [{ Type: 'tcp', Mode: 'server', IdDevice: '2', Time: '11:02:11', Data: '32,44,53' }]
  }
}

Edit1: SubRequest: when input:

var modbusData = [
  { Type: "rtu", Mode: "master", IdDevice: "1", Time: "11:01:00", Data: "1,12,23" },
  { Type: "tcp", Mode: "client", IdDevice: "2", Time: "11:01:11", Data: "30,40,50" },
];

I want output also contain Mode slave and server in empty array like this:

{
  rtu: {
    master: [{ Type: 'rtu', Mode: 'master', IdDevice: '1', Time: '11:01:00', Data: '1,12,23' }],
    slave: []
  },
  tcp: {
    client: [{ Type: 'tcp', Mode: 'client', IdDevice: '2', Time: '11:01:11', Data: '30,40,50' }],
    server: []
  }
}

1 Answer 1

1

You could put an extra step on the end re-using your groupBy method and making use of Object.entries and Object.fromEntries:

const subGroupedData = Object.fromEntries(Object.entries(groupedData)
    .map( ([key,values]) => ([key, groupBy(values,'Mode')])))

Live example:

var modbusData = [
  { Type: "rtu", Mode: "master", IdDevice: "1", Time: "11:01:00", Data: "1,12,23" },
  { Type: "tcp", Mode: "client", IdDevice: "2", Time: "11:01:11", Data: "30,40,50" },
  //{ Type: "rtu", Mode: "slave", IdDevice: "1", Time: "11:02:00", Data: "5,10,21" },
  //{ Type: "tcp", Mode: "server", IdDevice: "2", Time: "11:02:11", Data: "32,44,53" },
];

function groupBy(objectArray, property, expectedGroups = []) {
  return objectArray.reduce(function (acc, obj) {
    let key = obj[property]
    if (!acc[key]) {
      acc[key] = []
    }
    acc[key].push(obj)
    return acc
  }, Object.fromEntries(expectedGroups.map(k => [k, []])))
};
const groupedData = groupBy(modbusData, 'Type', [ 'rtu', 'tcp' ]);

const expectedSubGroups = {rtu: ['master','slave'], tcp:['client','server']}

const subGroupedData = Object.fromEntries(Object.entries(groupedData)
        .map( ([key,values]) => ([key, groupBy(values,'Mode', expectedSubGroups[key])])))

console.log(subGroupedData);

Sign up to request clarification or add additional context in comments.

3 Comments

I want an extra request: when Mode: "master" or "slave" not exist in Type : "rtu", as well as "client", "server" of "tcp". They will return empty array
@CSNo.1 Sorry, its not clear from your example what you want. Include in the question an input and output for which you would expect an empty array
@CSNo.1 does this now answer your question?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.