0

My objective here is to convert the input array into the structure of the output array. The input array and output array are shown below. If you observe carefully we can see that id is common in both the arrays and only title changes.

var output = [{
        id: "1",
        title: 'title',
        children: [],
    },
    {
        id: "2",
        title: 'title2',
        children: [],
    },
    {
        id: "3",
        title: 'title3',
        children: [{
            id: "4",
            title: 'title4',
            children: [],
        }, {
            id: "5",
            title: 'title5',
            children: [{
                id: "6",
                title: 'title6',
                children: [],
            }, {
                id: "7",
                title: 'title7',
                children: [],
            }, {
                id: "9",
                title: 'title9',
                children: [],
            }]
        }],
    }
]

var input = [{
        id: "1",
        title: 'title_chnaged',
        children: [],
    },
    {
        id: "2",
        title: 'title_changed',
        children: []
    },
    {
        id: "3",
        title: 'title_changed',
        children: [{
            id: "4",
            title: 'title_changed',
            children: [],
        }, {
            id: "5",
            title: 'title_changed',
            children: [],
            children: [{
                    id: "6",
                    title: 'title_changed',
                    children: [],
                },
                {
                    id: "7",
                    title: 'title_changed',
                    children: [],
                }
            ]
        }],
    },
    {
        id: "9",
        title: 'title_chnaged',
        children: [],
    }
]

This function will look into the input array of corresponding element of output array on the . basis of id

let found;

function findTheKey(id, widget) {
    let newObj = [...widget];
    for (var key in newObj) {
        if (newObj[key]["id"] == id) {
            found = newObj[key];
            break;
        }
        if (newObj[key].hasOwnProperty("children")) {
            findTheKey(id, newObj[key].children);
        }
    }
    return found;
}

This function will iterate over the output array and look for corresponding element in input array

function findAllObjectOnArray(output) {
    let newObj = [...output];
    for (let key in newObj) {
        newObj[key] = {
            ...findTheKey(newObj[key]['id'], input),
            children: newObj[key].children
        };
        if (newObj[key].hasOwnProperty("children")) {
            findAllObjectOnArray(newObj[key].children, input);
        }
    }
    return newObj;
}



var result = findAllObjectOnArray(output)
console.log(result)

The result is as expected on label 1 but as we move into nested object, it didn't changed.

Please suggest me something which will let it work. Any hint or solution is highly welcome ?

Harun Yilmaz
  • 8,281
  • 3
  • 24
  • 35
  • 1
    Your code doesn't do anything and it is unclear what you are trying to achieve. The data input to output appears to only walk the tree and set `this.title = "title"+this.id`, but the code is doing something complicated like walking the tree searching for `id`s – user120242 Apr 14 '20 at 07:13
  • Actually i want to replace the whole object of output array with the input array object on the basis of id @user120242 – Sunil Yadav Apr 14 '20 at 08:00
  • You mean a direct object reference replacement based on id? So output[0] === input[0] whereas input[0].id === output[0].id, and so on? Your code is using object clones so the references aren't being kept. – user120242 Apr 14 '20 at 08:06
  • is that possible to achieve the desired result if i do deep copy @user120242 ? – Sunil Yadav Apr 14 '20 at 08:12

2 Answers2

0

I've created a function fn that maps array elements to elemnts with property title = "title"+id and then recursively maps children nodes.

var output = [
{
 id: "1",
 title: 'title',
 children: [],
},
{
 id: "2",
 title: 'title2',
 children: [],
},
{
 id: "3",
 title: 'title3',
 children: [
 {
  id: "4",
  title: 'title4',
  children: [],
 },
 {
  id: "5",
  title: 'title5',
  children: [
  {
   id: "6",
   title: 'title6',
   children: [],
  },
  {
   id: "7",
   title: 'title7',
   children: [],
  },
  {
   id: "9",
   title: 'title9',
   children: [],
  }]
 }],
}]

var input = [
{
 id: "1",
 title: 'title_chnaged',
 children: [],
},
{
 id: "2",
 title: 'title_changed',
 children: []
},
{
 id: "3",
 title: 'title_changed',
 children: [
 {
  id: "4",
  title: 'title_changed',
  children: [],
 },
 {
  id: "5",
  title: 'title_changed',
  children: [],
  children: [
  {
   id: "6",
   title: 'title_changed',
   children: [],
  },
  {
   id: "7",
   title: 'title_changed',
   children: [],
  }]
 }],
},
{
 id: "9",
 title: 'title_chnaged',
 children: [],
}]

var fn =  node =>
 node && node.map( x => 
  ({
   ...x,
   title: "title"+x.id,
   children: fn(x.children)
  })
 )



var result = fn(output)
console.log(result)
user120242
  • 14,918
  • 3
  • 38
  • 52
0

A tip: Either stick to immutable (copy all objects) or modify it in-place. Things become really complicated when you mix the two unless you know what you are doing.

I'm not entirely sure if this is what you mean? It's hard to be sure if it works correctly because the title_changed strings are all the same. I just added newObj[key].children = findAllObjectOnArray(newObj[key].children); so that the children property gets updated correctly (since you make a clone of the array on every call, so children doesn't get updated when you try to modify it by reference).

    var output = [
    {
     id: "1",
     title: 'title',
     children: [],
    },
    {
     id: "2",
     title: 'title2',
     children: [],
    },
    {
     id: "3",
     title: 'title3',
     children: [
     {
      id: "4",
      title: 'title4',
      children: [],
     },
     {
      id: "5",
      title: 'title5',
      children: [
      {
       id: "6",
       title: 'title6',
       children: [],
      },
      {
       id: "7",
       title: 'title7',
       children: [],
      },
      {
       id: "9",
       title: 'title9',
       children: [],
      }]
     }],
    }]

    var input = [
    {
     id: "1",
     title: 'title_chnaged',
     children: [],
    },
    {
     id: "2",
     title: 'title_changed',
     children: []
    },
    {
     id: "3",
     title: 'title_changed',
     children: [
     {
      id: "4",
      title: 'title_changed',
      children: [],
     },
     {
      id: "5",
      title: 'title_changed',
      children: [],
      children: [
      {
       id: "6",
       title: 'title_changed',
       children: [],
      },
      {
       id: "7",
       title: 'title_changed',
       children: [],
      }]
     }],
    },
    {
     id: "9",
     title: 'title_chnaged',
     children: [],
    }]

let found;

function findTheKey(id, widget) {
    let newObj = [...widget];
    for (var key in newObj) {
        if (newObj[key]["id"] == id) {
            found = newObj[key];
            break;
        }
        if (newObj[key].hasOwnProperty("children")) {
            findTheKey(id, newObj[key].children);
        }
    }
    return found;
}

function findAllObjectOnArray(output) {
    let newObj = [...output];
    for (let key in newObj) {
        newObj[key] = {
            ...findTheKey(newObj[key]['id'], input),
            children: newObj[key].children
        };
        if (newObj[key].hasOwnProperty("children")) {
            newObj[key].children = findAllObjectOnArray(newObj[key].children);
        }
    }
    return newObj;
}

    var result = findAllObjectOnArray(output)
    console.log(result)
user120242
  • 14,918
  • 3
  • 38
  • 52