1

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?

1 Answer 1

1

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;
}

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

2 Comments

There is definitely no way to do this by some simple JS trick, but in case you are using associative arrays in JS Object you should get results quickly. Mind upvote or accept under voting buttons in case you are happy with...
This is fantastic thanks, I'll be able to use this as template for all my SQL to JavaScript.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.