Reputation: 536
I have a bunch of objects from multiple sources that I'd like to merge so I can work with one large object instead of say 5 or 10 objects.
Let's say my main object array with employees basic data that I'd like to push the other arrays to is
var employees = [
{emp_id: 1, emp_name: "John D", phone:"123456"},
{emp_id: 2, emp_name: "Mary J", phone:"234567"},
{emp_id: 3, emp_name: "Doe J", phone:"345678"},
{emp_id: 4, emp_name: "Jane M", phone:"456789"}
]
And another object array with the employees work history:
var employee_history = [
{emp_id: 1, company: "ABC", Years: 4},
{emp_id: 2, company: "BCD", Years: 3},
{emp_id: 3, company: "CDE", Years: 2},
{emp_id: 4, company: "DEF", Years: 1}
]
And a final object array with the employees residential history as:
var cities_lived = [
{emp_id: 1, city: "Moscow", Years: 1},
{emp_id: 1, city: "Doha", Years: 1},
{emp_id: 2, city: "Cairo", Years: 2},
{emp_id: 2, city: "London", Years: 1},
{emp_id: 3, city: "Tunis", Years: 2},
{emp_id: 3, city: "Beijing", Years: 2},
{emp_id: 4, city: "New York", Years: 1},
{emp_id: 4, city: "Capetown", Years: 1}
]
So I'd like to push employee_history
and cities_lived
into the individual objects inside employees
using the emp_id
property to match and have an output like this or something close as long as it's inside the individual object:
[
{
emp_id: 1,
emp_name: "John D",
phone: "123456",
company: "ABC",
Years: 4,
cities: [
{emp_id: 1, city: "Doha", Years: "1"},
{emp_id: 1, city: "Doha", Years: "1"}
]
},
{},
{},
...
]
How can I achieve this?
My cumbersome solution was to loop each object array and create new objects which I'd push the data to, then finally push the results into the main object array. But I don't like the idea of having to do all that manually and even then I'm not sure how to push the results into the main object array where the emp_id
properties match.
Upvotes: 1
Views: 1504
Reputation: 39250
You could try to write small functions that do little and combine them into one that will merge items into an item.
Then take all your data that needs to be merged with their merger function and reduce employees to a new value that has everything merged.
const employees = [{"emp_id":1,"emp_name":"John D","phone":"123456"},{"emp_id":2,"emp_name":"Mary J","phone":"234567"},{"emp_id":3,"emp_name":"Doe J","phone":"345678"},{"emp_id":4,"emp_name":"Jane M","phone":"456789"}];
const employee_history = [{"emp_id":1,"company":"ABC","Years":4},{"emp_id":2,"company":"BCD","Years":3},{"emp_id":3,"company":"CDE","Years":2},{"emp_id":4,"company":"DEF","Years":1}];
const cities_lived = [{"emp_id":1,"city":"Moscow","Years":1},{"emp_id":1,"city":"Doha","Years":1},{"emp_id":2,"city":"Cairo","Years":2},{"emp_id":2,"city":"London","Years":1},{"emp_id":3,"city":"Tunis","Years":2},{"emp_id":3,"city":"Beijing","Years":2},{"emp_id":4,"city":"New York","Years":1},{"emp_id":4,"city":"Capetown","Years":1}];
const whatever = [{ emp_id: 1, whatever: 'whatever' }];//extra to merge item
//merges items with the merger function from toMerge array in uniqueArray
// if they match using matcher
const mergeIn = (uniqueArray, toMerge, matcher, merger) =>
uniqueArray.map((item) =>
merger(item, toMerge.filter(matcher(item))),
);
//create a merger function set item[itemFieldName] with a mapped result
// of others using mapper function
const merger = (itemFieldName, mapper) => (
item,
others,
) => ({
...item,
[itemFieldName]: others.map(mapper),
});
//match on emp_id
const matchEpmId = (item) => (other) =>
item.emp_id === other.emp_id;
console.log(
[
[
cities_lived,
//merger function that sets item.cities with others mapped to {city,Years}
merger('cities', ({ city, Years }) => ({ city, Years}))
],
[
employee_history,
//merger function that sets item.history with others mapped to {company,Years}
merger('history', ({ company, Years }) => ({ company, Years}))
],
[
whatever,//extra to merge items
merger('whatever', ({ whatever }) => whatever),
],
].reduce(
(result, [other, merger]) =>
mergeIn(result, other, matchEpmId, merger),
employees,
),
);
Upvotes: 1
Reputation: 186
Yes, that is simple to do. You just need to iterate over employees and build the object along the way and at the end of loop you will have the desired result.
var employees = [
{ emp_id: 1, emp_name: "John D", phone: "123456" },
{ emp_id: 2, emp_name: "Mary J", phone: "234567" },
{ emp_id: 3, emp_name: "Doe J", phone: "345678" },
{ emp_id: 4, emp_name: "Jane M", phone: "456789" }
];
var employee_history = [
{ emp_id: 1, company: "ABC", Years: 4 },
{ emp_id: 2, company: "BCD", Years: 3 },
{ emp_id: 3, company: "CDE", Years: 2 },
{ emp_id: 4, company: "DEF", Years: 1 }
];
var cities_lived = [
{ emp_id: 1, city: "Moscow", Years: 1 },
{ emp_id: 1, city: "Doha", Years: 1 },
{ emp_id: 2, city: "Cairo", Years: 2 },
{ emp_id: 2, city: "London", Years: 1 },
{ emp_id: 3, city: "Tunis", Years: 2 },
{ emp_id: 3, city: "Beijing", Years: 2 },
{ emp_id: 4, city: "New York", Years: 1 },
{ emp_id: 4, city: "Capetown", Years: 1 }
];
employees.forEach(employee => {
const employeeHistory = employee_history.find(x => x.emp_id == employee.emp_id);
employee = { ...employee, ...employeeHistory };
const employeeCities = cities_lived.filter(x => x.emp_id === employee.emp_id);
employee.cities = [];
if (employeeCities && employeeCities.length > 0) {
employee.cities = employeeCities;
}
});
Upvotes: 1
Reputation: 2056
You need to iterate over cities and history array and create a map by emp_id as key. And insert into final object.
Try this
var employees = [
{emp_id: 1, emp_name: "John D", phone:"123456"},
{emp_id: 2, emp_name: "Mary J", phone:"234567"},
{emp_id: 3, emp_name: "Doe J", phone:"345678"},
{emp_id: 4, emp_name: "Jane M", phone:"456789"}
]
var employee_history = [
{emp_id: 1, company: "ABC", Years: 4},
{emp_id: 2, company: "BCD", Years: 3},
{emp_id: 3, company: "CDE", Years: 2},
{emp_id: 4, company: "DEF", Years: 1}
]
var cities_lived = [
{emp_id: 1, city: "Moscow", Years: 1},
{emp_id: 1, city: "Doha", Years: 1},
{emp_id: 2, city: "Cairo", Years: 2},
{emp_id: 2, city: "London", Years: 1},
{emp_id: 3, city: "Tunis", Years: 2},
{emp_id: 3, city: "Beijing", Years: 2},
{emp_id: 4, city: "New York", Years: 1},
{emp_id: 4, city: "Capetown", Years: 1}
]
var cities_lived_obj = cities_lived.reduce(function(o,i){
if(!o.hasOwnProperty(i.emp_id)){
o[i.emp_id] = [];
}
o[i.emp_id].push(i);
return o;
},{});
var employee_history_obj = employee_history.reduce(function(o,i){
if(!o.hasOwnProperty(i.emp_id)){
o[i.emp_id] = [];
}
o[i.emp_id].push(i);
return o;
},{});
employees.forEach(function(emp){
emp['cities'] = cities_lived_obj[emp.emp_id];
emp['history'] = employee_history_obj[emp.emp_id];
});
console.log(employees);
JsFiddle demo - https://jsfiddle.net/f3bh0eop/2/
Upvotes: 1