Reputation: 587
I have two JSON arrays like this. I want to merge their keyvalue pairs. They are some items which are common in both while they are some items which are uncommon.
var jsonData1 = [
{
firstName: "Sam",
age: "10"
},
{
firstName: "John",
age: "11"
},
{
firstName: "Jack",
age: "12"
},
{
firstName: "Pam",
age: "13"
},
{
firstName: "Tom",
age: "14"
},
{
firstName: "Mitch",
age: "15"
}
];
var jsonData2 = [
{
firstName: "Sam",
city: "London"
},
{
firstName: "John",
city: "New York"
},
{
firstName: "Jack",
city: "Paris"
},
{
firstName: "Pam",
city: "Moscow"
},
{
firstName: "Roger",
city: "Shanghai"
},
{
firstName: "Don",
city: "Jakarta"
}
];
As you can there are some firstName in 1st array which does not have city in 2nd array. Again there are some firstName in 2nd array which does not have city in 1st array.
I need to club these 2 array into one array, in case a firstName does not have age or city it will be assigned '' (blank string).
The new array will have 3 fields, there are some items which will be having values in 2 fields. They have a one field as blank string.
I want to do this using Vanilla JS, I do not want to use Jquery, Lodash and Underscore.
Upvotes: 2
Views: 2563
Reputation: 21672
I realize you've already accepted an answer but I figured I could provide an alternative, be it better or worse.
var jsonData1 = [{firstName: "Sam",age: "10"},{firstName: "John",age: "11"},{firstName: "Jack",age: "12"},{firstName: "Pam",age: "13"},{firstName: "Tom",age: "14"},{firstName: "Mitch",age: "15"}];
var jsonData2 = [{firstName: "Sam",city: "London"},{firstName: "John",city: "New York"},{firstName: "Jack",city: "Paris"},{firstName: "Pam",city: "Moscow"},{firstName: "Roger",city: "Shanghai"},{firstName: "Don",city: "Jakarta"}];
var defaults = {firstName: "", age: "", city: ""};
var data = [ ...jsonData1, ...jsonData2 ];
var names = [ ...new Set(data.map(i=>i.firstName)) ];
var res = names.map(n => data
.reduce((acc, jd) => jd.firstName === n ? {...acc, ...jd} : acc, defaults)
);
console.log(res);
var data
combines the two arrays of data into one using spread syntax (array literals).
var names
creates an array of unique names using Set
.
map()
iterates over the list of names, creating a single, merged object for each. That merge is done using reduce()
and spread syntax (object literals).
Upvotes: 0
Reputation: 30390
There are a number of ways to approach this, however one option would be to base this around the Array#reduce()
method as follows:
const jsonData1=[{firstName:"Sam",age:"10"},{firstName:"John",age:"11"},{firstName:"Jack",age:"12"},{firstName:"Pam",age:"13"},{firstName:"Tom",age:"14"},{firstName:"Mitch",age:"15"}];
const jsonData2=[{firstName:"Sam",city:"London"},{firstName:"John",city:"New York"},{firstName:"Jack",city:"Paris"},{firstName:"Pam",city:"Moscow"},{firstName:"Roger",city:"Shanghai"},{firstName:"Don",city:"Jakarta"}];
/*
Use Array#concat() to combine both input arrays before performing
the merge. This will ensure that all items in both arrays are
processed and accounted for during the merge (which is important in
situations where the input arrays differ in length).
Object.values() is used to transform the dictionary resulting from
reduce() to an array
*/
var result = Object.values(
[].concat(jsonData1, jsonData2
).reduce((dict, item) => {
/*
We use Array#reduce is an intermediate step to construct a dictionary
which maps each unique "item.firstName" to a corresponding object
that contains the merged (or yet to be merged) data for this first
name
*/
var value = dict[item.firstName] || {}
/*
Use Object.assign() to merge existing data for "item.firstName" with
current item being processed. Also pass default values as first
argument to ensure all three key values are present in merge result
*/
value = Object.assign({ firstName : '', age : '', city : ''} , value, item)
/*
Update the dictionary with merged data
*/
dict[item.firstName] = value
return dict
}, {}))
console.log(result);
Upvotes: 3
Reputation: 4488
One possible approach:
const jsonData1=[{firstName:"Sam",age:"10"},{firstName:"John",age:"11"},{firstName:"Jack",age:"12"},{firstName:"Pam",age:"13"},{firstName:"Tom",age:"14"},{firstName:"Mitch",age:"15"}];
const jsonData2=[{firstName:"Sam",city:"London"},{firstName:"John",city:"New York"},{firstName:"Jack",city:"Paris"},{firstName:"Pam",city:"Moscow"},{firstName:"Roger",city:"Shanghai"},{firstName:"Don",city:"Jakarta"}];
const result = [].concat(jsonData1, jsonData2).reduce((acc, ele) => {
const existing = acc.find(x => x.firstName === ele.firstName);
if(!existing) return acc.concat({firstName: ele.firstName, city: ele.city || '', age: ele.age || ''});
Object.keys(ele).forEach(x => existing[x] = ele[x]);
return acc;
},[])
console.log(result);
Upvotes: 0