Flattening json with an key exclusion list

Viewed 88

I need to flatten the json, but want to consider an exclusion_keys_array list which are not to be processed/added to the list

for example

if I have an exclusion_keys_array = ["addresses.metadata", "pageToken"] //only metadata of addresses will be skipped (second level skip)

if I have an exclusion_keys_array = ["metadata", "pageToken"] //metadata of parent json will be skipped (top level key skip)

How do I flatten a JSON using an exclusion array?

Code source: Dynamically generate a 2d array from JSON with varying columns

var exlusion_list = ["metadata", "meta", "pageToken"];

var crowds = [{
  "name": [{
    "firstName": "John",
    "middleName": "Joseph",
    "lastName": "Briggs",
  }],
  "addresses": [{
    "type": "home",
    "poBox": "111",
    "city": "City1",
    "postalCode": "1ER001",
    "country": "USA",
  }, {
    "type": "work",
    "poBox": "222",
    "city": "City2",
    "region": "Region2",
    "postalCode": "1ER002",
  }],
  "photos": [{
    "url": "photo.org/person1",
    "default": true,
  }, {
    "url": "imagur.org/person1",
    "default": true,
  }],
  "metadata": [{
    "meta-id": "1234",
  }],
}, {
  "name": [{
    "firstName": "Bill",
    "lastName": "Thatcher",
  }],
  "addresses": [{
    "type": "home",
    "city": "City3",
    "region": "Region3",
    "postalCode": "1ER003",
    "country": "USA",
  }, {
    "type": "work",
    "poBox": "444",
    "region": "Region4",
    "postalCode": "1ER004",
  }, {
    "poBox": "555",
    "region": "Region5",
    "postalCode": "1ER005",
  }],
  "metadata": [{
    "meta-id": "1234",
  }],
}];

function flatten(obj, res = {}, key = '') {
  let add = (d, s) => key ? key + d + s : s;

  if (Array.isArray(obj)) {
    obj.forEach((v, n) => flatten(v, res, add(' #', n + 1)));
  } else if (typeof obj === 'object') {
    Object.entries(obj).forEach(([k, v]) => flatten(v, res, add(': ', k)));
  } else {
    res[key] = obj;
  }
  return res;
}
let flats = crowds.map(obj => flatten(obj));

function combineKeys(objs) {
  let keys = objs.reduce((k, obj) => k.concat(Object.keys(obj)), []);
  return [...new Set(keys)];
}
let keys = combineKeys(flats);

let table = flats.map(f => keys.map(k => f[k] ?? ''));

table.unshift(keys);

console.log({ table });
// document.write(JSON.stringify(table));
.as-console-wrapper { min-height: 100%!important; top: 0; }
// .as-console-wrapper { min-height: 70%!important; bottom: 0; }

1 Answers

A quick fix would be filter the keys like below. I think there is a more efficient way to do it but I didn't look into the codes too deep.

let keys = combineKeys(flats).filter(
  key => !exlusion_list.includes(key.split(":")[0].split(" ")[0])
);
Related