Home > Enterprise >  Filter and transform json with javascript
Filter and transform json with javascript

Time:05-19

Using Javascript, I need all the elements inside "group"."1" to have the following value value:

{"schemas": "block"}

Also, I need that the elements inside "group"."101" to have the following value:

{"schemas": "all",
"native": "write"}

The original json looks like this:

 {
  "revision": 76,
  "groups": {
    "1": {
      "26": {
        "schemas": "block"
      },
      "138": {
        "schemas": "block"
      },
      "179": {
        "schemas": "block"
      },
      "245": {
        "schemas": "all",
        "native": "write"
      }
    },
    "101": {
      "167": {
        "schemas": "block"
      }
    }
  }
}

The expected result looks like this

{
  "revision": 76,
  "groups": {
    "1": {
      "26": {
        "schemas": "block"
      },
      "138": {
        "schemas": "block"
      },
      "179": {
        "schemas": "block"
      },
      "245": {
        "schemas": "block"
      }
    },
    "101": {
      "167": {
       "schemas": "all",
       "native": "write"
      }
    }
  }
}

CodePudding user response:

const res = JSON.parse(JSON.stringify(json))

Object.keys(res.groups.1).forEach(key => res.groups.1[key] = {"schemas": "block"}
Object.keys(res.groups.101).forEach(key => res.groups.101[key] = {"schemas": "all",
"native": "write"}

is a direct solution, because you are starting from a json object so the JSON serialization copy should succeed.

we can generalize by splitting a path into an array and applying that in a "filter" step, then applying a function.

const filterTransformFactory = (filter, transform) => json => {
  head = json
  while(filter.length) {
    head = head[filter.shift()]
  }
  Object.keys(head).forEach(key => transform(head, key))
}

const oneFilter = filterTransformFactory(['groups', 1], (o, key) => o[key] = {"schemas": "block"})
const oneooneFilter = filterTransformFactory(['groups', 101], (o, key) => o[key] = {"schemas": "all",
    "native": "write"})

and apply that to a copy of the json. a bit further refactoring can make this rather pretty, by providing a replaceTransform function:

const filterTransformFactory = (filter, transform) => json => {
  head = json
  while(filter.length) {
    head = head[filter.shift()]
  }
  Object.keys(head).forEach(key => transform(head, key))
}
const replaceTransformFactory = payload => (o, key) => o[key] = payload

const oneTransform = replaceTransformFactory({"schemas": "block"})
const oneFilterTransform = filterTransformFactory(['groups', 1], oneTransform)

const oneooneTransform = replaceTransformFactory({"schemas": "all", "native": "write"})
const oneooneFilterTransform = filterTransformFactory(['groups', 101], oneooneTransform)

const result = JSON.parse(JSON.stringify(json))
oneFilterTransform(result)
oneooneFilterTransform(result)

CodePudding user response:

I created a config object with all the groups we want to transform and their respective values. Then just iterated over the groups and replaced the values.

const transform = (json, config) => {
  Object.keys(json.groups).forEach(group => {
    // Skip groups that are not in config
    if (!(group in config)) return;

    const keys = Object.keys(json.groups[group]);
    for (const key of keys) {
      json.groups[group][key] = { ...config[group] };
    }
  });
};

// All the the groups we want to transform
const config = {
  "1": {
    "schemas": "block"
  },
  "101": {
    "schemas": "all",
    "native": "write"
  }
};

const json = {
  "revision": 76,
  "groups": {
    "1": {
      "26": {
        "schemas": "block"
      },
      "138": {
        "schemas": "block"
      },
      "179": {
        "schemas": "block"
      },
      "245": {
        "schemas": "all",
        "native": "write"
      }
    },
    "101": {
      "167": {
        "schemas": "block"
      }
    }
  }
};

transform(json, config);
console.log(json);

  • Related