我有两个具有多个对象的数组
[
{
"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个对象,并且匹配这些对象的唯一方法是使用"employee_id"
和"e_id"
。
答案 0 :(得分:1)
为了匹配employee_id
和e_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)
答案 1 :(得分: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)}));
答案 2 :(得分: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] }));
答案 3 :(得分:0)
一种略有不同的方法,只是使用带有循环的vanilla js map
来匹配员工ID,并将第二个数组中的数据添加到第一个数组中的匹配对象中。我的猜测是,@MarkMeyer的答案可能会更快。
let arr1 = [{
"name": "paul",
"employee_id": "8"
}]
let arr2 = [{
"years_at_school": 6, "department": "Mathematics",
"e_id": "8"
}]
let results = arr1.map(obj1 => {
for (let obj2 of arr2) {
if (obj2.e_id === obj1.employee_id) {
obj1.data = obj2;
break;
}
}
return obj1;
});
console.log(results);
答案 4 :(得分:0)
您的问题表明两个数组的大小始终相同。它还建议您将array2
的内容放在data
中具有相同索引的元素的字段array1
中。如果这些假设是正确的,则:
// 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);
});