3

So I have a query output somewhat like this (using knex):

response = [
  {id: 1, source: 'mobile', ms_payment.id: 111, ms_payment.total: 100},
  {id: 2, source: 'mobile', ms_payment.id: 112, ms_payment.total: 210},
  ...
]

And the expected output (mapped output) to return in REST API is:

result = [
  {id: 1, source: 'mobile', ms_payment: { id: 111, total: 100 }},
  {id: 2, source: 'mobile', ms_payment: { id: 112, total: 210 }},
]

Is there any efficient algorithm using javascript? I am currently doing it manually with Array.map(), which just returns the expected output schema, without any looping or methods.

Thank you in advance.

Evan Gunawan
  • 387
  • 4
  • 17

3 Answers3

2

You need to iterate the entries and get nested objects.

const
    setValue = (object, key, value) => {
        const
            keys = key.split('.'),
            last = keys.pop();
            
        keys.reduce((o, k) => o[k] ??= {}, object)[last] = value;
        return object;
    },
    response = [{ id: 1, source: 'mobile', 'ms_payment.id': 111, 'ms_payment.total': 100 }, { id: 2, source: 'mobile', 'ms_payment.id': 112, 'ms_payment.total': 210 }],
    result = response.map(o => Object
        .entries(o)
        .reduce((r, [k, v]) => setValue(r, k, v), {})
    );

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392
1

You can use the map function.

let response = [
  {id: 1, source: 'mobile', "ms_payment.id": 111, "ms_payment.total": 100},
  {id: 2, source: 'mobile', "ms_payment.id": 112, "ms_payment.total": 210},
];
let newResponse = [];
newResponse = response.map(obj => {
  let newObj = {...obj};
  Object.keys(obj).map(objKey => {
    if (objKey.toString().indexOf(".") >= 0) {
      let nodes = objKey.toString().split(".");
      let parent = nodes[0];
      let child = nodes[1];
      if (newObj.parent) {
        newObj.parent[child] = obj[objKey];
      } else {
        newObj.parent = {};
        newObj.parent[child] = obj[objKey];
      }
      delete newObj[objKey];
    }
  })
  return newObj;
});
console.log(newResponse);
awmidas
  • 653
  • 5
  • 13
0

You can map your array like this:

response = [{
    id: 1,
    source: 'mobile',
    'ms_payment.id': 111,
    'ms_payment.total': 100
  },
  {
    id: 2,
    source: 'mobile',
    'ms_payment.id': 112,
    'ms_payment.total': 210
  },
];

const result = response.map((item) => {
  return {
    id: item.id,
    source: item.source,
    ms_payment: {
      id: item['ms_payment.id'],
      total: item['ms_payment.total']
    }
  }
});

console.log(result);
firatozcevahir
  • 892
  • 4
  • 13