revetinja
revetinja

Reputation: 85

Need to merge two array of objects if one key value is the same

I have two fields of data - array of objects that I need to merge

let orders = [ 
    { 
        "email": "[email protected]",
        "field_1": null,
        "field_2": "This has some value",
        "field_3": null,
        "field_4": null,
        "field_5": 1
    }, 
    { 
        "email": "[email protected]",
        "field_1": null,
        "field_2": "This has some value",
        "field_3": null,
        "field_4": null
        "field_5": 2
    },
    { 
        "email": "[email protected]",
        "field_1": null,
        "field_2": "This has some other value",
        "field_3": null,
        "field_4": null,
        "field_5": 250
    },

    ];

let contacts = [ 
    { 
        "email": "[email protected]",
        "field_1": "Name1",
        "field_2": null,
        "field_3": "Address 1"
        "field_4": true
        "field_5": 1
    }, 
    { 
        "email": "[email protected]",
        "field_1": "Name2",
        "field_2": null,
        "field_3": "Address 2"
        "field_4": true
        "field_5": 2
    }
];

What I need is to merge the two arrays into one, where they are only connected by unique field which is email, and to override all those null fields. I need first array of objects null fields populated from the contacts array based by email.

What I have tried so far was merging the two arrays, but because all of the fields exists in both of objects, it doesn't override them. So I tried removing the null elements from the first array, as they will be added from the second, but most of the null fields from the second array override those with data in the first one.

I could remove the null items in the second array as well and then merge them, but I need all of the fields to show.

Is there any better way to do this?

data1.forEach(element => {
  Object.keys(element).forEach(key => {
    if(element[key] === null) return delete element[key]

    return element[key]
  })
})

const newArr = _.merge(data1, data2);

Expected resulting array would be:

let orders = [ 
    { 
        "email": "[email protected]",
        "field_1": "Name1",
        "field_2": "This has some value",
        "field_3": "Address 1",
        "field_4": true,
        "field_5": 1
    }, 
    { 
        "email": "[email protected]",
        "field_1": "Name2",
        "field_2": "This has some value",
        "field_3": "Address 2",
        "field_4": true
        "field_5": 2
    },
    { 
        "email": "[email protected]",
        "field_1": "Name1",
        "field_2": "This has some other value",
        "field_3": "Address 1",
        "field_4": true,
        "field_5": 250
    },

];

Upvotes: 0

Views: 97

Answers (1)

Code Maniac
Code Maniac

Reputation: 37757

You can use Map and map

  • Map contact by email
  • Loop over orders, find if there's any contact with same email is present in mapper.
  • Loop over the keys of current element and check if the value is null or not
  • If it is null replace with value from mapper else keep it as it is

let orders = [{"email": "[email protected]","field_1": null,"field_2": "This has some value","field_3": null,"field_4": null,"field_5": 1},{"email": "[email protected]","field_1": null,"field_2": "This has some value","field_3": null,"field_4": null, "field_5": 2},{"email": "[email protected]","field_1": null,"field_2": "This has some other value","field_3": null,"field_4": null,"field_5": 250},];
let contacts = [{"email": "[email protected]","field_1": "Name1","field_2": null,"field_3": "Address 1","field_4": true, "field_5": 1},{"email": "[email protected]","field_1": "Name2","field_2": null,"field_3": "Address 2","field_4": true ,"field_5": 2}];

let mapper = new Map(contacts.map(v => [v.email, v]))

let final = orders.map(v => {
  let contact = mapper.get(v.email)
  if (contact) {
    for (let key in v) {
      if (v[key] === null) {
        v[key] = contact[key]
      }
    }
  }
  return v
})

console.log(final)

Upvotes: 2

Related Questions