2

I have two array object array1 and array2, I want to merge the data on the basis of the key name

array1= [
    {
        name:"adam",
        data:[
            
        ]
    },
    {
        name:"eve",
        data:[
            [
                "child"
            ],
            [
                "secondchild"
            ]
        ]
    }
]
array2= [
    {
        name:"adam",
        data:[
            [
                "thirdchild"
            ],
            [
                "fourthchild"
            ]
        ]
    },
    {
        name:"eve",
        data:[
            
        ]
    }
]

the output should be

result= [
    {
        name:"adam",
        data:[
            [
                "thirdchild"
            ],
            [
                "fourthchild"
            ]
        ]
    },
    {
        name:"eve",
        data:[
            [
                "child"
            ],
            [
                "secondchild"
            ]
        ]
    }
]

I have been able to get the object index but I am not able to push the array inside data, I am not able to write down the code here as I am working on a virtual machine. any hint or help would be appreciated.

I am running a map of array1 and inside it, I am running another map of array 2 but I don't think its the optimized way of doing

array1.map(el => {
array2.map(es => {
if(el.name === es.name){
/// here I am doing the logic , is there any optimized ways 
}
})})
Mohammad Zubair
  • 413
  • 4
  • 12

3 Answers3

2

Just convert both arrays to keyMaped object, by this way we avoid some array function call overhead.... :

keymap = {};//both of arrays will be mapped here

array1.map(e => {
    if(keymap[e.name]){
        keymap[e.name].data = [...keymap[e.name].data, ...e.data];
    }else{
        keymap[e.name] = {data: e.data};
    }
});

array2.map(e => {
    if(keymap[e.name]){//merge arrays
        keymap[e.name].data = [...keymap[e.name].data, ...e.data];
    }else{
        keymap[e.name] = {data: e.data};
    }
});

then make result from key map

//make result from keymap:
result = [];
for (var key in keymap) { 
    if (!keymap.hasOwnProperty(key)) continue;//avoid processing native properties... 
    result.push({name: key, data: keymap[key].data}); 
}
Mamrezo
  • 1,309
  • 16
  • 20
0

let array1= [
    {
        name:"adam",
        data:[
            
        ]
    },
    {
        name:"eve",
        data:[
            [
                "child"
            ],
            [
                "secondchild"
            ]
        ]
    }
]
let array2= [
    {
        name:"adam",
        data:[
            [
                "thirdchild"
            ],
            [
                "fourthchild"
            ]
        ]
    },
    {
        name:"eve",
        data:[
            
        ]
    }
]

let r = array1.map(row=>{
   row.data=[...row.data, ...array2.find(f=>f.name===row.name)?.data ?? []];
   return row;
})

console.log(r);
Vahid Alimohamadi
  • 4,900
  • 2
  • 22
  • 37
  • Could you point out how this is different from what the OP is already doing? You just replaced `array2.map` and the `name` comparison with `array2.find`, which I think are doing the same thing. – maazadeeb Apr 05 '21 at 20:44
  • array.find will break the loop when it reaches to elem. Yes it is o(n2) but better than a complete map. In my opinion o(n2) better than creating another array in memory. Optimization is not only the time complexity of algorithm. @maazadeeb – Vahid Alimohamadi Apr 05 '21 at 20:49
  • 1
    Thanks for clarifying. It would be better if you explained it as part of your answer. Code only answers are usually hard for the OP to understand. – maazadeeb Apr 05 '21 at 21:05
0

Firstly, if the number of elements in the array are not too large, there is really no need to worry about whether this is optimised or not.

Assuming that the number of elements in the arrays are so large that the nested loops (O(n^2)) are a problem, you can create a temporary map of the elements of one array with name as key, and then match while iterating over the other array.

const array1 = [{
    name: "adam",
    data: [

    ]
  },
  {
    name: "eve",
    data: [
      [
        "child"
      ],
      [
        "secondchild"
      ]
    ]
  }
];
const array2 = [{
    name: "adam",
    data: [
      [
        "thirdchild"
      ],
      [
        "fourthchild"
      ]
    ]
  },
  {
    name: "eve",
    data: [

    ]
  }
];

const a1Map = array1.reduce((map, a1) => {
  map[a1.name] = a1;
  return map;
}, {});

const result = array2.map(a2 => {
  return {
    name: a2.name,
    data: [...a1Map[a2.name].data, ...a2.data]
  }
});

console.log(result)

Note that since data is an array of arrays, you might need to create a deep copy depending on your use case.

maazadeeb
  • 5,922
  • 2
  • 27
  • 40
  • 1
    It should add the new object in the case when the initial array2 has an extra object like { name: "michael", data: [] } it should push the whole object in the final array the final result should be [ { "name": "adam", "data": [ [ "thirdchild" ], [ "fourthchild" ] ] }, { "name": "eve", "data": [ [ "child" ], [ "secondchild" ] ] },{ name: "michael" ,data : []} ] – Mohammad Zubair Jun 14 '21 at 20:16
  • 1
    @MohammadZubair you could do that by checking if `a1Map[a2.name]` exists or not, inside the `array2.map(...)`. – maazadeeb Jun 14 '21 at 21:53