1

we have an array like this. I want to add the new child and increment the "id".

[  
   {  
      "name":"Headcount",
      "id":1,
      "parentId":0,
      "is_open":true,
      "children":[  
         {  
            "name":"temp1",
            "id":2,
            "parentId":1,
            "is_open":true,

         },
         {  
            "name":"Temp",
            "id":90
         }
      ]
   },
{  
      "name":"temp2",
      "id":4,
      "parentId":0,
      "is_open":true,
      "children":[  
         {  
            "name":"temp3",
            "id":5,
            "parentId":4,
            "is_open":true,
            "children":[  
               {  
                  "name":"temp4",
                  "id":6,
                  "parentId":5,
                  "is_open":true   }
      ]
   }
]

We want to add a new ID to the newly added child node.

we have tried adding the new id by finding the max value in an array and add it to the new child node.

the code we tried is

var res = Math.max.apply(Math,data.map(function(o){return o.id;}))
         console.log("Max ID res:"+res);

It gives the answer as "4" but we want it "90" since it is the largest number. how to iterate through Child nodes and find/increment the new "id".

Thanks in advance for your help.

claasic
  • 1,050
  • 6
  • 14
Narasappa
  • 546
  • 1
  • 9
  • 31

1 Answers1

1

Not fully fleshed out but the general idea goes as follows: Since it's a heavily nested structure we avoid recursion or any deep search by transforming the structure into a string and traverse it then via regex.

First we get all "id" entries which we then use as starting points for new matches that return us the digits after each index. Then on those numbers we apply a reduce to find the maximum and we are done. You can now apply the number into your new structure.

I wasn't sure which part of the structure is part of the to be searched part so I just searched the whole structure for the highest id there is.

let data = [  
   {  
      "name":"Headcount",
      "id":1,
      "parentId":0,
      "is_open":true,
      "children":[  
         {  
            "name":"temp1",
            "id":2,
            "parentId":1,
            "is_open":true,

         },
         {  
            "name":"Temp",
            "id":90
         }
      ]
   },
{  
      "name":"temp2",
      "id":4,
      "parentId":0,
      "is_open":true,
      "children":[  
         {  
            "name":"temp3",
            "id":5,
            "parentId":4,
            "is_open":true,
            "children":[  
               {  
                  "name":"temp4",
                  "id":6,
                  "parentId":5,
                  "is_open":true   }
      ]
   }
]
}]

let f = (data) => {
  // https://stackoverflow.com/a/3410557/9758920
  let s = JSON.stringify(data), regex = /"id"/gi, result, indices = [];
  while ( (result = regex.exec(s)) ) {
    indices.push(result.index);
  }

  let ids = []
  for (i of indices) {
    ids.push(s.slice(i,i+10).match(/\d+/g)[0]) // not optimal by any means
  }
  return ids.reduce((m,c) => (m > c) ? m : c)
}

console.log(f(data))

The following should be a bit quicker:

let f = (data) => {
  return JSON.stringify(data)
          .match(/"id":\d+/g)
          .reduce((m,c) => {
            let tmp = +c.slice(5);
            return (m > tmp) ? m : tmp})
}
claasic
  • 1,050
  • 6
  • 14
  • Thank you, your code works perfectly for two digit numbers. I added the new child with the help of this code but once the "id" crosses 100,it gives the result as 99 is the maximum number.How to solve it? – Narasappa Jul 03 '19 at 13:52
  • @Narasappa That is easy: `ids.push(s.slice(i,i+10).match` change the 10 to a 11 and so on, depending on how many digits you need! The code only tries to match a certain slice starting at the index, so by extending the slice size you get to match bigger numbers. – claasic Jul 03 '19 at 13:55
  • Thanks for your immediate response. I tried ids.push(s.slice(i,i+1000).match . but it didn't work. where am I going wrong? – Narasappa Jul 04 '19 at 13:42
  • 1
    Change the return line to `return ids.reduce((m,c) => (m > c) ? +m : +c)`. Also `i + 10` should be enough to cover most cases. – claasic Jul 04 '19 at 13:59
  • 1
    @Narasappa I added a quicker version of the function to it. – claasic Jul 05 '19 at 12:05
  • 1
    Your answer Proved to be very helpful to us.We had been trying it for four days. – Narasappa Jul 06 '19 at 07:23
  • Glad to be of help :) – claasic Jul 06 '19 at 09:41