Jack Clayton
Jack Clayton

Reputation: 448

SQL results into nested Javascript object

I have SQL results that are returned in Javascript like this:

{
  machine_class: 'MAN',
  machine: '001',
  start: '2020-01-02 18:27:38',
  end: '2020-01-02 18:30:22',
  code: 'ready'
},
{
  machine_class: 'CMD',
  machine: '002',
  start: '2020-01-02 18:30:22',
  end: '2020-01-02 18:30:53',
  code: 'ready'
},
{
  machine_class: 'CMD',
  machine: '002',
  start: '2020-01-02 18:30:53',
  end: '2020-01-02 18:31:16',
  code: 'delay'
},
{
  machine_class: 'CMD',
  machine: '003',
  start: '2020-01-02 18:31:16',
  end: '2020-01-02 18:31:29',
  code: 'ready'
}

I need to nest the results first by machine_class, then by machine like this:

[
  {
    machine_class: "CMD",
    data: [
      {
        machine: "002",
        data: [
          {
            timeRange: ['2020-01-02 18:30:22', '2020-01-02 18:30:53'],
            val: 'ready' 
          },
          {
            timeRange: ['2020-01-02 18:30:53', '2020-01-02 18:31:16'],
            val: 'delay'
          },
          (...)
        ]
      },
      {
        machine: "003",
        data: [...]
      },
      (...)
    ],
  },
  {
    machine_class: "MAN",
    data: [...]
  },
  (...)
]

The only solutions I can come up with are complicated and slow, is there anything inbuilt to JavaScript that can nest objects like this?

Upvotes: 1

Views: 113

Answers (1)

Jan
Jan

Reputation: 2249

Should not be so slow in case you are using Object for indexing, is output OK ?

Below line is also indexed source to better understand how it works as it is a data driven algo.

var dbInput = [{ machine_class: 'MAN', machine: '001', start: '2020-01-02 18:27:38', end: '2020-01-02 18:30:22', code: 'ready' }, { machine_class: 'CMD', machine: '002', start: '2020-01-02 18:30:22', end: '2020-01-02 18:30:53', code: 'ready' }, { machine_class: 'CMD', machine: '002', start: '2020-01-02 18:30:53', end: '2020-01-02 18:31:16', code: 'delay' }, { machine_class: 'CMD', machine: '003', start: '2020-01-02 18:31:16', end: '2020-01-02 18:31:29', code: 'ready' }];
var res = convert(dbInput);
var merge = res.pop();
document.body.innerHTML = '<PRE>var Result = ' + JSON.stringify(res,null,2) + '</PRE>' +
'<HR>' +
'<PRE>var IndexedSource = ' + JSON.stringify(merge,null,2) + '</PRE>';
function convert (dbInput) {
    var merge = {};
    for (var r = 0; r < dbInput.length; r++) {
        var row = dbInput[r]; var classIndex; var machineIndex;
        do {
            classIndex = merge[row.machine_class];
            merge[row.machine_class] = classIndex || {};
        } while (classIndex === undefined);
        do {
            machineIndex = classIndex[row.machine];
            classIndex[row.machine] = machineIndex || [];
        } while (machineIndex === undefined);
        machineIndex.push({
            timeRange: [row.start, row.end],
            val: row.code
        });
    }
    var result = [];
    for (var machineClass in merge) {
        var machineClassElement = {
            machine_class: machineClass,
            data: []
        };
        result.push(machineClassElement);
        var data = machineClassElement.data;
        machineClassElement = merge[machineClass];
        for (var machine in machineClassElement) {
            data.push({
                machine: machine,
                data: machineClassElement[machine]
            });
        }
    }
    result.push(merge); // merged data before final reorder
    return result;
}

Upvotes: 1

Related Questions