TiJi
TiJi

Reputation: 33

Turning 2 level JSON to multiple 1 level JSON in Node.js

I have problems with writing a universal function in node that would parse JSON like this:

{
    "parserId": 1,
    "filters": [
        {
            "filterName": "replaceTitle",
            "regex": "..."
        },
        {
            "filterName": "replaceRegion",
            "regex": "..."
        }
]}

into multiple JSON like this:

{ "parserId": 1, "filterName": "replaceTitle","regex": "..." },{ "parserId": 1, "filterName": "replaceRegion", "regex": "..."}

It would be great if this function would be universal so doesn't matter what are the names of the fields in JSON, as long as it's build the same way. Is there any node package already doing it? Thank you for your help!

Upvotes: 2

Views: 1092

Answers (2)

Nina Scholz
Nina Scholz

Reputation: 386540

You could map every item of the array and append an object with parserId with the item of the array.

var object = { parserId: 1, filters: [{ filterName: "replaceTitle", regex: "..." }, { filterName: "replaceRegion", regex: "..." }] },
    array = object.filters.map(o => Object.assign({ parserId: object.parserId }, o));

console.log(array);
.as-console-wrapper { max-height: 100% !important; top: 0; }

A more general approach could be the check if a property is an array and loop that array later or add the property to a common object, which keeps the same values for all new generated objects.

Later iterate the arrays and add the content to the objects as well.

This works without specifying the properties who are arrays or just values.

function unnormalize(object) {
    var common = {};

    return Object
        .keys(object)
        .filter(k => Array.isArray(object[k]) || (common[k] = object[k], false))
        .reduce((r, k) => (object[k].forEach((o, i) => Object.assign(r[i] = r[i] || Object.assign({}, common), o)), r), []);
}

var object = { parserId: 1, filters: [{ filterName: "replaceTitle", regex: "..." }, { filterName: "replaceRegion", regex: "..." }] };

console.log(unnormalize(object));
.as-console-wrapper { max-height: 100% !important; top: 0; }

Upvotes: 1

user184994
user184994

Reputation: 18271

You can use square bracket syntax to provide the name of the array. Then you can use map to transform the array, and Object.assign to merge the objects

let data = {
    "parserId": 1,
    "filters": [
        {
            "filterName": "replaceTitle",
            "regex": "..."
        },
        {
            "filterName": "replaceRegion",
            "regex": "..."
        }
]};


function format(data) {
  let array = data.filters;
  // Remove the array so that it's not duplicated
  delete data.filters;
  return array.map((item) => Object.assign(item, data));
}

console.log(format(data));

Upvotes: 0

Related Questions