Home > Blockchain >  I want to push id and parent in a nested JSON array of objects
I want to push id and parent in a nested JSON array of objects

Time:09-05

I have nested JSON

[
{
    "heading": [
        {
            "name": "Heading 01",
            "Items": [
                {
                    "name": "Item 01",
                    "layers": [
                        {
                            "name": "layer01",
                        },
                        {
                            "name": "layer02",
                        }
                    ]
                }
            ]
        }
    ]
}
]

I am trying to push id, parent and draggable key value pair to nested JSON and output should be like this

[{
    "id": 1,
    "parent": 0,
    "droppable":true,
    "heading": [
        {
            "name": "Heading 01",
            "id": 2,
            "parent": 1,
            "droppable":true,
            "Items": [
                {
                    "name": "Item 01",
                    "id": 3,
                    "parent": 2,
                    "droppable":true,
                    "layers": [
                        {
                            "name": "layer01",
                            "parent": 3,
                            "id":4,
                            "droppable":false
                        },
                        {
                            "name": "layer02",
                            "parent": 3,
                            "id":4,
                            "droppable":false
                        }
                    ]
                }
            ]
        }
    ]
  }]

But when I tried using arr.forEach I am not getting the expected output.

let treedata = [
{
    "heading": [
        {
            "name": "Heading 01",
            "Items": [
                {
                    "name": "Item 01",
                    "layers": [
                        {
                            "name": "layer01",
                        },
                        {
                            "name": "layer02",
                        }
                    ]
                }
            ]
        }
    ]
}
]
  function addUniqueID(arr) {
    arr.forEach((obj, i) => {
      obj.parent = JSON.parse (`${i}`);
      obj.id = JSON.parse(`${i}`);
      obj.text =`${i}`;
      if (obj.heading) {
        addUniqueID(obj.heading);
      }
      // if (obj.layers) {
      //   addUniqueID(obj.layers);
      // }
    });
  }
  addUniqueID(treedata);
  console.log(treedata);

CodePudding user response:

You have to use recursion and pass id as a parameter. Something like this:

let treedata = [
{
    "heading": [
        {
            "name": "Heading 01",
            "Items": [
                {
                    "name": "Item 01",
                    "layers": [
                        {
                            "name": "layer01",
                        },
                        {
                            "name": "layer02",
                        }
                    ]
                }
            ]
        }
    ]
}
]
  function addUniqueID(arr, id) {
    arr.forEach((obj, i) => {
      obj.parent = id - 1;
      obj.id = id;
      if (obj.heading) {
        addUniqueID(obj.heading, id   1);
      }
      if (obj.Items) {
        addUniqueID(obj.Items, id   1);
      }
      if (obj.layers) {
        addUniqueID(obj.layers, id   1);
      }
    });
  }
  addUniqueID(treedata, 1);
  console.log(treedata);

CodePudding user response:

Here's an approach,

const data = [{ heading: [{name: "Heading 01", Items: [{name: "Item 01", layers: [{name: "layer01"}, { name: "layer02"}]}]}]}];

const addUniqueId = (arr, parentId) => {
  const listKeys = ["heading", "Items", "layers"];

  return arr.map((item, index) => {
    const newId = parentId   index   1;
    const result = {
      ...item,
      id: newId,
      parent: parentId,
    };

    let droppable = false;
    listKeys.forEach((key) => {
      if (item[key]?.length) {
        droppable = true;
        result[key] = addUniqueId(item[key], newId);
      }
    });

    return { ...result, droppable };
  });
};


console.log(addUniqueId(data, 0));

CodePudding user response:

How about this recursion? passing parent along the tree so that id would get proper value.

var data = [{
  "heading": [{
    "name": "Heading 01",
    "Items": [{
      "name": "Item 01",
      "layers": [{
          "name": "layer01",
        },
        {
          "name": "layer02",
        }
      ]
    }]
  }]
}]


const iterate = (obj, parent) => {
  if (!obj) {
    return;
  }
  parent = parent || 0;
  var my_id = parent

  Object.keys(obj).forEach(key => {
    var value = obj[key]
    if (typeof value === "object" && value !== null) {
      if (!Array.isArray(value)) {
        value.parent = parent;
        value.id =   my_id
        value.droppable = true;
      }
      iterate(value, my_id)
    }
  })
}
iterate(data);
console.log(data);
.as-console-wrapper {
  max-height: 100% !important;
}

CodePudding user response:

Pass the id as parameter to the function and increase by one in each depth.

let treedata = [
    {
        "heading": [
            {
                "name": "Heading 01",
                "Items": [
                    {
                        "name": "Item 01",
                        "layers": [
                            {
                                "name": "layer01",
                            },
                            {
                                "name": "layer02",
                            }
                        ]
                    }
                ]
            }
        ]
    }
    ];
    function addUniqueID(arr, i) {
      arr.forEach((obj) => {
        obj.parent = i;
        obj.id = i   1;
        obj.text = i   "";
        obj.droppable = true;
        if (obj.heading) {
          addUniqueID(obj.heading, i 1);
        }
        else if (obj.layers) {
           addUniqueID(obj.layers, i 1);
        }
        else if (obj.Items) {
           addUniqueID(obj.Items, i 1);
        } else {
          obj.droppable = false;
        }
      });
    }
    addUniqueID(treedata, 0);
    console.log(treedata);

CodePudding user response:

Anoter one recursive solution

const treedata = [{heading: [{name: "Heading 01",Items: [{name: "Item 01","layers": [{name: "layer01"},{name: "layer02"}]}]}]}];

const makeNextId = () => {
  let count = 0;
  return () => count  = 1;
};
const nextId = makeNextId();

const iter = (arr, id, parent = 0) => arr.map((obj) => {
  const arrayKeys = Object.keys(obj).filter((key) => Array.isArray(obj[key]));
  const droppable = Boolean(arrayKeys.length);
  return { 
    ...obj, 
    id, 
    parent, 
    droppable, 
    ...Object.fromEntries(arrayKeys.map((key) =>  [key, iter(obj[key], nextId(), id)] ))
  }
});


const result = iter(treedata, nextId());

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

  • Related