Выдвиньте массив объектов JS в другой массив объектов с соответствующим ключом объекта - PullRequest
0 голосов
/ 08 ноября 2018

У меня есть набор объектов из нескольких источников, которые я хотел бы объединить, чтобы я мог работать с одним большим объектом вместо, скажем, 5 или 10 объектов.

Скажем, мой основной объектный массив с базовыми данными сотрудников, к которым я бы хотел добавить другие массивы, -

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}
]

Так что я бы хотел вставить employee_history и cities_lived в отдельные объекты внутри employees, используя свойство emp_id, чтобы сопоставить и получить вывод, подобный этому или что-то близкое, если он находится внутри отдельного объекта :

[
{
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"}
] 
},
{},
{},
...
]

Как мне этого добиться?

Мое громоздкое решение состояло в том, чтобы зациклить каждый массив объектов и создать новые объекты, в которые я бы помещал данные, а затем, наконец, помещать результаты в массив основных объектов. Но мне не нравится идея делать все это вручную, и даже тогда я не уверен, как поместить результаты в массив основных объектов, где совпадают свойства emp_id.

Ответы [ 3 ]

0 голосов
/ 08 ноября 2018

Да, это просто сделать. Вам просто нужно перебрать сотрудников и построить объект по пути, и в конце цикла вы получите желаемый результат.

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;
  }
});
0 голосов
/ 08 ноября 2018

Вы можете попытаться написать небольшие функции, которые мало что делают, и объединить их в одну, которая объединит элементы в элемент.

Затем возьмите все свои данные, которые должны быть объединены, с их функцией слияния и приведите сотрудников к новому значению, в котором есть все объединенное.

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,
  ),
);
0 голосов
/ 08 ноября 2018

Вам нужно перебрать массив городов и истории и создать карту по ключу emp_id. И вставить в конечный объект.

Попробуйте это

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/

...