Home > OS >  inserting item into a nested javascript object
inserting item into a nested javascript object

Time:12-21

how does one go about inserting an item into a nested javascript array of objects (with and without using a library)? running to a problem where once you insert the item after traversing, how would you reassign it back to the original object without manually accessing the object like data.content[0].content[0].content[0] etc..? already tried Iterate through Nested JavaScript Objects but could not get the reassignment to work

const data = {
    "content": [
        {
            "name": "a",
            "content": [
                {
                    "name": "b",
                    "content": [
                        {
                            "name": "c",
                            "content": []
                        }
                    ]
                }
            ]
        }
    ]
}

inserting {"name": "d", "content": []} into the contents of c

const data = {
    "content": [
        {
            "name": "a",
            "content": [
                {
                    "name": "b",
                    "content": [
                        {
                            "name": "c",
                            "content": [{"name": "d", "content": []}]
                        }
                    ]
                }
            ]
        }
    ]
}

CodePudding user response:

const data = {
  "content": [{
    "name": "a",
    "content": [{
      "name": "b",
      "content": [{
        "name": "c",
        "content": []
      }]
    }]
  }]
}

const insert = createInsert(data)

insert({
  "name": "d",
  "content": []
}, 'c')

console.log(data)

// create a new function that will be able to insert items to the object
function createInsert(object) {
  return function insert(obj, to) {
    // create a queue with root data object
    const queue = [object]
    // while there are elements in the queue
    while (queue.length) {
      // remove first element from the queue
      const current = queue.shift()
      // if name of the element is the searched one
      if (current.name === to) {
        // push the object into the current element and break the loop
        current.content.push(obj)
        break
      }
      // add child elements to the queue
      for (const item of current.content) {
        queue.push(item)
      }
    }
  }
}

CodePudding user response:

It looks like we should assume that the name property uniquely identifies an object in the data structure. With that assumption you could create a mapping object for it, so to map a given name to the corresponding object in the nested structure. Also keep track which is the parent of a given object.

All this meta data can be wrapped in a decorator function, so that the data object gets some capabilities to get, add and remove certain names from it, no matter where it is in the hierarchy:

function mappable(data) {
    const map = { "__root__": { content: [] } };
    const parent = {};
    const dfs = (parentName, obj) => {
        parent[obj.name] = parentName;
        map[obj.name] = obj;
        obj.content?.forEach?.(child => dfs(obj.name, child));
    }
    
    Object.defineProperties(data, {
        get: { value(name) {
             return map[name];
        }},
        add: { value(parentName, obj) {
            this.get(parentName).content.push(obj);
            dfs(parentName, obj);
        }},
        remove: { value(name) {
            map[parent[name]].content = map[parent[name]].content.filter(obj =>
                obj.name != name
            );
            delete map[name];
            delete parent[name];
        }}
    });
    data.add("__root__", data);
}

// Demo
const data = {"content": [{"name": "a","content": [{"name": "b","content": [{"name": "c","content": []}]}]}]};

mappable(data);
data.add("c", { name: "d", content: [] });
console.log(data);
console.log(data.get("d")); // { name: "d", content: [] }
data.remove("d");
console.log(data.get("d")); // undefined
console.log(data); // original object structure

  • Related