2

Background

I transformed a non-trivial JSON response that uses arrays into

  • a nested object
  • eliminating some of the original properties
  • inserting a new summary property that is a unique list of values from the original object

I did this with temporary variables, foreach loops and some conditional logic. My first working code, sample input / output JSON are below.

Question / Concern

While this works, I'm concerned about the "smell" of the code and the maintainability. Is there a way to do this that would be more maintainable (perhaps with Array. ..., map, filter, reduce) ? I'm not looking for a working solution but more than "one liners".

CODE

const raw = require('./tests/data/raw.json');

function parseLoc(loc) {
  const types = new Set();

  // constant properties with loc_id the name of the object
  let o = { [loc.loc_id]: { last_update: loc.last_update, type_id: loc.type_id } };
  types.add(loc.type_id);
  // optional property
  if (loc.contents) {
    o = { [loc.loc_id]: { ...o[loc.loc_id], contents: loc.contents } };
    loc.contents.forEach((item) => {
      types.add(item.type_id); // can have nested types
    });
  }
  // optional property
  if (loc.plan_id) {
    o = { [loc.loc_id]: { ...o[loc.loc_id], plan_id: loc.plan_id } };
  }
  // summary properties
  o = {
    [loc.loc_id]: {
      ...o[loc.loc_id],
      Types: [...types],
    },
  };
  return o;
}

const driver = () => {
  const { locs } = raw[Object.keys(raw)[0]];

  let out = {};
  locs.forEach((loc) => {
    const t = parseLoc(loc);
    out = { ...out, [Object.keys(t)[0]]: t[Object.keys(t)[0]] };
  });
  console.log('out', out);
};

driver();

Input

   {
  "Input": {
    "locs": [
      {
        "contents": [{ "amount": 1, "type_id": 2393 }],
        "last_update": "2013-09-22T21:53:51Z",
        "obsolete1": 1.52384062551,
        "obsolete2": 1.56361060962,
        "loc_id": 1011160470678,
        "type_id": 2524
      },
      {
        "last_update": "2019-07-29T10:56:27Z",
        "obsolete1": 1.60921860432,
        "obsolete2": 1.60545414964,
        "loc_id": 1028580652821,
        "plan_id": 97,
        "type_id": 2474
      },
      {
        "contents": [
          { "amount": 560, "type_id": 2393 },
          { "amount": 560, "type_id": 9838 },
          { "amount": 560, "type_id": 2317 },
        ],
        "last_update": "2019-02-28T22:09:51Z",
        "obsolete1": 1.55924075537,
        "obsolete2": 1.58171860958,
        "loc_id": 1029669382563,
        "type_id": 2544
      }
    ]
  }
}

OUTPUT

{
  "Output": {
    "types": [2393, 9838, 2524, 2474, 2312],
    "locs": {
      "1011160470678": {
        "last_update": "2013-09-22T21:53:51Z",
        "type_id": 2524
      },
      "1028580652821": {
        "contents": [{ "amount": 560, "type_id": 9838 }],
        "last_update": "2019-07-29T10:56:27Z",
        "plan_id": 97,
        "type_id": 2474
      },
      "1029669382563": {
        "contents": [
          { "amount": 560, "type_id": 2393 },
          { "amount": 560, "type_id": 9838 },
          { "amount": 560, "type_id": 2317 }
        ],
        "last_update": "2019-02-28T22:09:51Z",
        "type_id": 2544
      }
    }
  }
}
Timothy Vogel
  • 1,363
  • 2
  • 21
  • 39
  • 1
    Why don't you post what you have tried, showing the expected output, and explain why what you have does not work? If it works, it's not a good fit for SO. Maybe it's mutating and you don't want to mutate? It's always best to show what you have tried. Otherwise we are just writing code for you! – Ruan Mendes Aug 09 '19 at 17:00
  • Juan, ... thanks for taking the time to read my post. I've edited it and included working code. – Timothy Vogel Aug 09 '19 at 18:43
  • Timothy, as I mentioned, if it works, it's not a good fit for StackOverflow. How about https://codereview.stackexchange.com/ ? Having said that, it looks readable to me and I don't think map, filter and reduce would make it more maintainable. It may make it more elegant, but potentially harder to understand. – Ruan Mendes Aug 09 '19 at 18:56
  • Thanks again for your input. I did take your suggestion and posted this on codereview. – Timothy Vogel Aug 09 '19 at 20:05
  • Link to codereview post: https://codereview.stackexchange.com/questions/225849/real-world-json-transformation-using-javascript-node-is-there-a-better-approa (also, +1 for `{[someKeyishValue]: 'Hello' }` syntax, I didn't know one can do that) – Fabian N. Aug 09 '19 at 20:16
  • I think of the square brackets when used like that as a dereference operator (*) from my old "C" days. – Timothy Vogel Aug 09 '19 at 20:33
  • This question belongs on another site in the Stack Exchange network https://codereview.stackexchange.com/ – Dale K Aug 10 '19 at 00:04

0 Answers0