4

我有两个有多个对象的数组

[
     {
         "name":"paul",
         "employee_id":"8"
     }
]

[
     {
         "years_at_school": 6,
         "department":"Mathematics",
         "e_id":"8"
     }
]

如何使用 ES6 或 Lodash 实现以下目标?

[
     {
         "name":"paul",
         "employee_id":"8"
         "data": {
             "years_at_school": 6
             "department":"Mathematics",
             "e_id":"8"
         }
     }
]

我可以合并,但我不确定如何创建一个新的子对象并将其合并。

我试过的代码:

school_data = _.map(array1, function(obj) {
    return _.merge(obj, _.find(array2, {employee_id: obj.e_id}))
})

这会合并到像这样的顶级数组(这不是我想要的):

{
     "name":"paul",
     "employee_id":"8"
     "years_at_school": 6
     "department":"Mathematics",
     "e_id":"8"
 }

这两者之间的连接器是"employee_id""e_id"

必须考虑到它们可能是每个数组中的 1000 个对象,并且匹配这些对象的唯一方法是 by"employee_id""e_id"

4

5 回答 5

1

为了匹配employee_ide_id您应该遍历第一个数组并创建一个以employee_id. 然后您可以遍历第二个数组并将数据添加到相关的特定 id。这是一个示例,每个数组都添加了一个额外的项目:

let arr1 = [
    {
        "name":"mark",
        "employee_id":"6"
    },
    {
        "name":"paul",
        "employee_id":"8"
    }
]

let arr2 = [
    {
        "years_at_school": 6,
        "department":"Mathematics",
        "e_id":"8"
    },
    {
        "years_at_school": 12,
        "department":"Arr",
        "e_id":"6"
    }
    
]

// empObj will be keyed to item.employee_id 
let empObj = arr1.reduce((obj, item) => {
    obj[item.employee_id] = item
    return obj
}, {})

//  now lookup up id and add data for each object in arr2
arr2.forEach(item=>
    empObj[item.e_id].data = item
)

// The values of the object will be an array of your data
let merged = Object.values(empObj)
console.log(merged)

于 2018-09-29T04:03:41.560 回答
1

如果你执行两个嵌套的 O(n) 循环(map+find),你最终会得到 O(n^2) 的性能。一个典型的替代方法是创建中间索引结构,所以整个事情是 O(n)。使用 lodash 的函数式方法:

const _ = require('lodash');
const dataByEmployeeId = _(array2).keyBy('e_id');
const result = array1.map(o => ({...o, data: dataByEmployeeId.get(o.employee_id)}));
于 2018-09-29T19:45:02.743 回答
0

希望这对您有所帮助:

var mainData = [{
   name: "paul",
   employee_id: "8"
}];

var secondaryData = [{
  years_at_school: 6,
  department: "Mathematics",
  e_id: "8"
}];

var finalData = mainData.map(function(person, index) {
  person.data = secondaryData[index];
  return person;
});

抱歉,我还修复了第二个对象中缺少的昏迷并更改了一些其他内容。

使用最新的 Ecmascript 版本:

const mainData = [{
   name: "paul",
   employee_id: "8"
}];

const secondaryData = [{
  years_at_school: 6,
  department: "Mathematics",
  e_id: "8"
}];

// Be careful with spread operator over objects.. it lacks of browser support yet! ..but works fine on latest Chrome version for example (69.0)
const finalData = mainData.map((person, index) => ({ ...person, data: secondaryData[index] }));

于 2018-09-29T04:26:55.377 回答
0

一种稍微不同的方法,只是使用map带有循环的 vanilla js 来匹配员工 ID,并将第二个数组中的数据添加到第一个数组中的匹配对象中。我的猜测是@MarkMeyer的答案可能更快。

const arr1 = [{ "name": "paul", "employee_id": "8" }];
const arr2 = [{ "years_at_school": 6, "department": "Mathematics", "e_id": "8" }];
const results = arr1.map((obj1) => {
  for (const obj2 of arr2) {
    if (obj2.e_id === obj1.employee_id) {
      obj1.data = obj2;
      break;
    }
  }
  
  return obj1;
});

console.log(results);

于 2018-09-29T04:44:08.913 回答
0

您的问题表明两个数组将始终具有相同的大小。它还建议您要将 的内容放在具有相同索引的元素array2的字段中。如果这些假设是正确的,那么:dataarray1

// Array that will receive the extra data
const teachers = [
    { name: "Paul", employee_id: 8 },
    { name: "Mariah", employee_id: 10 }
];

// Array with the additional data
const extraData = [
    { years_at_school: 6, department: "Mathematics", e_id: 8 },
    { years_at_school: 8, department: "Biology", e_id: 10 },
];

// Array.map will iterate through all indices, and gives both the
const merged = teachers.map((teacher, index) => Object.assign({ data: extraData[index] }, teacher));

但是,如果您希望将数据添加到两个数组中都匹配“id”的员工,则需要执行以下操作:

// Create a function to obtain the employee from an ID
const findEmployee = id => extraData.filter(entry => entry.e_id == id);

merged = teachers.map(teacher => {
    const employeeData = findEmployee(teacher.employee_id);

    if (employeeData.length === 0) {
        // Employee not found
        throw new Error("Data inconsistency");
    }

    if (employeeData.length > 1) {
        // More than one employee found
        throw new Error("Data inconsistency");
    }

    return Object.assign({ data: employeeData[0] }, teacher);
});
于 2018-09-29T04:56:51.070 回答