Search code examples
javascriptnested-object

Check if the nested object contains a specific key, then replace a key of the parent object


I've a nested object.

Now, I need to check if the object contains 'items' as a key anywhere which is an 'array' always, then replace 'type' : 'list' by 'type': 'array' of the parent.

It works well for the 1st level but when it comes to the nested object which contains 'items' again, I'm stuck.

function convertData() {
 const arr = {
  "type": "list",
  "items": [{
   "type": "list",
   "items": [{
    "type": "string",
    "value": 0,
    "unit": "",
    "pattern": "^(auto|0)$|^[+-]?[0-9]+(\\.)?([0-9]+)?(rem|px|em|ex|%|in|cm|mm|pt|pc)$"
   }, {
    "type": "string",
    "value": 0.1875,
    "unit": "rem",
    "pattern": "^(auto|0)$|^[+-]?[0-9]+(\\.)?([0-9]+)?(rem|px|em|ex|%|in|cm|mm|pt|pc)$"
   }, {
    "type": "string",
    "value": 0.75,
    "unit": "rem",
    "pattern": "^(auto|0)$|^[+-]?[0-9]+(\\.)?([0-9]+)?(rem|px|em|ex|%|in|cm|mm|pt|pc)$"
   }, {
    "type": "string",
    "value": 0,
    "unit": "",
    "pattern": "^(auto|0)$|^[+-]?[0-9]+(\\.)?([0-9]+)?(rem|px|em|ex|%|in|cm|mm|pt|pc)$"
   }]
  }, {
   "type": "string",
   "value": {
    "r": 161,
    "g": 161,
    "b": 161,
    "a": 0.75,
    "hex": "#a1a1a1"
   },
   "pattern": "^rgba?\\(((25[0-5]|2[0-4]\\d|1\\d{1,2}|\\d\\d?)\\s*,\\s*?){2}(25[0-5]|2[0-4]\\d|1\\d{1,2}|\\d\\d?)\\s*,?\\s*([01]\\.?\\d*?)?\\)"
  }]
 };
 if (Array.isArray(arr.items)) {
  arr.type = "array";
  console.log(arr);
 }
}
<button onclick="convertData()">Click me!</button>


Solution

  • You can do that using recursion.

    • Create a function changeValue which takes an object as argument.
    • Check the object has key items using Object.hasOwnProperty()
    • If it contains change the type to "array" and call the function recursively on its each item.

    function convertData() {
     const arr = { "type": "list", "items": [{ "type": "list", "items": [{ "type": "string", "value": 0, "unit": "", "pattern": "^(auto|0)$|^[+-]?[0-9]+(\\.)?([0-9]+)?(rem|px|em|ex|%|in|cm|mm|pt|pc)$" }, { "type": "string", "value": 0.1875, "unit": "rem", "pattern": "^(auto|0)$|^[+-]?[0-9]+(\\.)?([0-9]+)?(rem|px|em|ex|%|in|cm|mm|pt|pc)$" }, { "type": "string", "value": 0.75, "unit": "rem", "pattern": "^(auto|0)$|^[+-]?[0-9]+(\\.)?([0-9]+)?(rem|px|em|ex|%|in|cm|mm|pt|pc)$" }, { "type": "string", "value": 0, "unit": "", "pattern": "^(auto|0)$|^[+-]?[0-9]+(\\.)?([0-9]+)?(rem|px|em|ex|%|in|cm|mm|pt|pc)$" }] }, { "type": "string", "value": { "r": 161, "g": 161, "b": 161, "a": 0.75, "hex": "#a1a1a1" }, "pattern": "^rgba?\\(((25[0-5]|2[0-4]\\d|1\\d{1,2}|\\d\\d?)\\s*,\\s*?){2}(25[0-5]|2[0-4]\\d|1\\d{1,2}|\\d\\d?)\\s*,?\\s*([01]\\.?\\d*?)?\\)" }] };
     changeValue(arr);
     console.log(arr)
    }
    
    function changeValue(obj){
      if(obj.hasOwnProperty('items')){
        obj.type = "array";
        obj.items.forEach(x => changeValue(x))
      }
    }
    <button onclick="convertData()">Click me!</button>