Home > Blockchain >  How to add or update items in this multidimensional JSON?
How to add or update items in this multidimensional JSON?

Time:08-11

Let's say we have some houses represented as JSON. Something like this:

[
    {
        "id": "1",
        "code": "1",
        "name": "Smith's",
        "children": [
            {
                "id": "",
                "code": "11",
                "name": "Kitchen",
                "children": [
                    {
                        "id": "",
                        "code": "111",
                        "name": "Sink",
                        "children": []
                    }
                ]
            },
            {
                "id": "",
                "code": "12",
                "name": "Living Room",
                "children": [
                    {
                        "id": "",
                        "code": "121",
                        "name": "Television",
                        "children": [
                            {
                                "id": "",
                                "code": "1211",
                                "name": "Panel buttons",
                                "children": [
                                    {
                                        "id": "",
                                        "code": "12111",
                                        "name": "Power button",
                                        "children": []
                                    },
                                    {
                                        "id": "",
                                        "code": "12112",
                                        "name": "Colors adjust button",
                                        "children": []
                                    }
                                ]
                            },
                            {
                                "id": "",
                                "code": "1221",
                                "name": "Screen",
                                "children": []
                            }
                        ]
                    }
                ]
            }
        ]
    },
    {
        "id": "2",
        "code": "2",
        "name": "Taylor's",
        "children": [
            // Here goes all house places and items like the example above
        ]
    },
    {
        "id": "1",
        "code": "1",
        "name": "Wilson's",
        "children": [
            // Here goes all house places and items like the example above
        ]
    }
]

Take notice that the "code" property, found in each item, is something to represent the "path" until that item, carrying its parents "code" property concatenated with its own position by incremental order. So the code "11" means house 1 and child 1. And 212 would be house 2, child 1, child 2. Also take notice that all items follow the same type. In other words, every item has a children that follows its own type. So, it could be infinite.

Now, I'd like to maintain these structure. Adding items, updating items and so on. Let's say we want to add a carpet in Smith's living room. We would go deep in the structure 2 levels, which are Smith's house (index 0 of the array) and living room (index 1 of the children array). And then add a carpet.

The problem is it won't be 2 levels in all cases. What if I wanted to add a bathroom? It would be level 1, alongside with kitchen in living room (the first children). What if I'd like to add a microwave in the kitchen and add to it buttons, display, etc?

I think I'm a recursive scenario where I have to visit all items and, if it is the one I'm looking to reach at, add/updated it.

I've tried following this example

I couldn't figure it out how to bring it to my case. though.

I appreciate if your contribution is in JavaScript, but feel free to represent it in other language in case you are better in other language =).

CodePudding user response:

There are indeed some questions, like for instance what happens if you have more than 10 items as child and why do you need it? And what happens if you remove any item on any level? will you recursively start updating all codes?

Nevertheless I gave it a go. In essence what I do in the code is first search for the parent (example: Kitchen) where you want to add it to and then add the new child item (example: Carpet) to it.

The search is a typical recursive search. The child addition is a typical addition to an array. For argument's sake I assumed that the fields code always exist and that children is always an array.

// Actual code is underneath the declaration of this array
let houseList = [
    {
        "id": "1",
        "code": "1",
        "name": "Smith's",
        "children": [
            {
                "id": "",
                "code": "11",
                "name": "Kitchen",
                "children": [
                    {
                        "id": "",
                        "code": "111",
                        "name": "Sink",
                        "children": []
                    }
                ]
            },
            {
                "id": "",
                "code": "12",
                "name": "Living Room",
                "children": [
                    {
                        "id": "",
                        "code": "121",
                        "name": "Television",
                        "children": [
                            {
                                "id": "",
                                "code": "1211",
                                "name": "Panel buttons",
                                "children": [
                                    {
                                        "id": "",
                                        "code": "12111",
                                        "name": "Power button",
                                        "children": []
                                    },
                                    {
                                        "id": "",
                                        "code": "12112",
                                        "name": "Colors adjust button",
                                        "children": []
                                    }
                                ]
                            },
                            {
                                "id": "",
                                "code": "1221",
                                "name": "Screen",
                                "children": []
                            }
                        ]
                    }
                ]
            }
        ]
    },
    {
        "id": "2",
        "code": "2",
        "name": "Taylor's",
        "children": [
            // Here goes all house places and items like the example above
        ]
    },
    {
        "id": "1",
        "code": "1",
        "name": "Wilson's",
        "children": [
            // Here goes all house places and items like the example above
        ]
    }
]

addChild(houseList,"11",{name:"Carpet" });
addChild(houseList,"1211",{name: "Volume Up Button"});
addChild(houseList,"1211",{name: "Volume Down Button"});
console.log('new houselist', houseList);

// child is just what you want to add and the parentCode refers to where you want to add it to
function addChild(houseList, parentCode, child) {
    let parent = findInHouseList(houseList,parentCode,child);
  let amountOfChildren = parent.children.length;
  let newCodeName = parentCode  ""  (amountOfChildren 1);
  child = {...{id: "", code: newCodeName, children: []}, ...child};
  console.log('adding child ', child);
  
  parent.children = [...parent.children, child];
}

function findInHouseList(houseList,code) {
    for (let house of houseList) {
    
    let foundElement = findElement(house,code);
    if ( foundElement)
        return foundElement;
  }
}

function findElement(currentElement, code) {
    if ( currentElement.code === code)
    return currentElement;
    
  if (currentElement.children?.length > 0)
    {
        for (let child of currentElement.children) {
        let foundElement = findElement(child,code);
        if ( foundElement)
            return foundElement;
      }
    }
  
  return null;
}

I decided to let the code manage the code names for new children. It seems the easiest.

CodePudding user response:

What you're trying to do is updating a JSON value at a dynamic path. You can achieve it by using recursion.

This function will append a child to the item which holds the specified code. You may add conditions to check if the item at the code is defined

function appendChild(houses, code, item) {
    let path = code.split('')
    let o = houses

    for (let i = 0; i < path.length; i  ) {
        let n = path[i] - 1
        o = o[n]["children"]
    }

    o.push(item)

    return houses
}

However, you should start your code indexes at 0 and storing them inside the JSON is useless since they are simply the path to reach the item.

  • Related