我正在尝试将一个数组中的对象值添加到另一个数组中的另一个对象中
第一个数组结构是:
var array1 = [
{ email: 'user1@example.com', status: 'offline' },
{ email: 'user2@example.com', status: 'online' },
{ email: 'user3@example.com', status: 'idle' }
]
var array2 = [
{ email: 'user1@example.com', status: '', activeTime: '1hr', logedIn: true, },
{ email: 'user1@example.com', status: '', activeTime: '1hr', logedIn: true, },
{ email: 'user1@example.com', status: '', activeTime: '1hr', logedIn: true, },
{ email: 'user2@example.com', status: '', activeTime: '2hr', logedIn: false, },
{ email: 'user2@example.com', status: '', activeTime: '2hr', logedIn: false, },
{ email: 'user2@example.com', status: '', activeTime: '2hr', logedIn: false, },
{ email: 'user2@example.com', status: '', activeTime: '2hr', logedIn: false, },
{ email: 'user3@example.com', status: '', activeTime: '1.5hr', logedIn: true, },
]
预期结果将是这样的:
var arrayJoined = [
{ email: 'user1@example.com', status: 'offline', activeTime: '1hr', logedIn: true, },
{ email: 'user1@example.com', status: 'offline', activeTime: '1hr', logedIn: true, },
{ email: 'user1@example.com', status: 'offline', activeTime: '1hr', logedIn: true, },
{ email: 'user2@example.com', status: 'online', activeTime: '2hr', logedIn: false, },
{ email: 'user2@example.com', status: 'online', activeTime: '2hr', logedIn: false, },
{ email: 'user2@example.com', status: 'online', activeTime: '2hr', logedIn: false, },
{ email: 'user2@example.com', status: 'online', activeTime: '2hr', logedIn: false, },
{ email: 'user3@example.com', status: 'idle', activeTime: '1.5hr', logedIn: true, },
]
答案 0 :(得分:5)
您将要映射到第二个数组,并将两个对象合并在一起,其中电子邮件是相同的。因此,您可以使用Array.map和Object.assign:
function merge(array1, array2) {
return array2.map(obj => {
var matchingObj = array1.find(el => el.email === obj.email)
return Object.assign({}, obj, matchingObj)
})
}
答案 1 :(得分:1)
您可以使用Map
和map
,与Map
相比,array1
将使find
中的搜索值更快
let array1 = [{ email: 'user1@example.com', status: 'offline' },{ email: 'user2@example.com', status: 'online' },{ email: 'user3@example.com', status: 'idle' }]
let array2 = [{ email: 'user1@example.com', status: '', activeTime: '1hr', logedIn: true, },{ email: 'user1@example.com', status: '', activeTime: '1hr', logedIn: true, },{ email: 'user1@example.com', status: '', activeTime: '1hr', logedIn: true, },{ email: 'user2@example.com', status: '', activeTime: '2hr', logedIn: false, },{ email: 'user2@example.com', status: '', activeTime: '2hr', logedIn: false, },{ email: 'user2@example.com', status: '', activeTime: '2hr', logedIn: false, },{ email: 'user2@example.com', status: '', activeTime: '2hr', logedIn: false, },{ email: 'user3@example.com', status: '', activeTime: '1.5hr', logedIn: true, }]
let maped = new Map([ array1.map(v => [v.email,v]) ])
function merge (array1, array2) {
return array2.map(obj => {
var matchingObj = maped.get(obj.email)
return Object.assign({}, obj, matchingObj)
})
}
console.log(merge(array1,array2))
答案 2 :(得分:1)
尝试使用foreach
和find
方法:
var array1 = [
{ email: 'user1@example.com', status: 'offline' },
{ email: 'user2@example.com', status: 'online' },
{ email: 'user3@example.com', status: 'idle' }
]
var array2 = [
{ email: 'user1@example.com', status: '', activeTime: '1hr', logedIn: true, },
{ email: 'user1@example.com', status: '', activeTime: '1hr', logedIn: true, },
{ email: 'user1@example.com', status: '', activeTime: '1hr', logedIn: true, },
{ email: 'user2@example.com', status: '', activeTime: '2hr', logedIn: false, },
{ email: 'user2@example.com', status: '', activeTime: '2hr', logedIn: false, },
{ email: 'user2@example.com', status: '', activeTime: '2hr', logedIn: false, },
{ email: 'user2@example.com', status: '', activeTime: '2hr', logedIn: false, },
{ email: 'user3@example.com', status: '', activeTime: '1.5hr', logedIn: true, },
];
// short version if status always has value:
array2.forEach(f=>{
f.status = array1.find(a1 => a1.email == f.email).status;
});
console.log(array2);
如果要检查状态是否有值:
array2.forEach(f=>{
const emailStatus = array1.find(a1 => a1.email == f.email);
if (emailStatus && emailStatus.status)
f.status = emailStatus.status;
});
答案 3 :(得分:0)
我在编写此书的前提是您正在学习Javascript,因此请记住,这并不是确定的“最佳方式”答案,而是说明您如何使用语言的各个方面来解决问题。您可能已经知道。
看来array1
基本上是您的具有当前状态的用户数据库。因此,您需要遍历array2
并从array1
中的相应对象复制属性。
有多种方法可以解决此问题。最幼稚的方式是:
var arrayJoined = [];
for (var i=0; i<array2.length; i++){
for(var n=0; n<array1.length; n++){
if (array1[n].email == array2[i].email){
tempObj = array2[i]; //See warning below
tempObj.status = array1[n].status;
arrayJoined.push(tempObj.status)
}
}
}
但是,这有很多问题:
for
循环非常困难,而且效率也不高。tempObj = array2[i]
位并不像您想象的那样起作用,因为它只是为现有对象分配了tempObj
引用;也就是说,对tempObj
进行更改也会影响array2[i]
。相反,让我们做一些优化:
array
创建一个哈希表,以避免循环并简化查找主要用户对象的过程(或者仅使用带有电子邮件的对象作为键)。 array2
中的对象添加属性var arr1hash = {};
for (var i=0; i<array1.length; i++){
arr1hash[array[i].email] = i;
}
// {'user1@example.com': 1, 'user2@example.com: 2, etc.}
for (var n=0; n<array2.length; n++){
var email = array2[n];
var index = arr1hash[email];//remember that arr1hash has the 'email' as a key and index in array1 as the value
array2[i].status = array1[index].status;
}
//Now the objects in array2 will have a completed 'status' key, populated from the first object
这更容易阅读,效率更高。如果您坚持使用数组作为此信息的数据结构,我不知道如何做得更好。
但是,如果您可以控制这些结构的创建方式,则可以选择效率更高的方法。您可以创建一个对象来充当用户“数据库”,而不是使用对象数组,并使用一个通用的唯一标识符将用户数据与日志中的数据相关联:
var users = {
'1': {email: 'foo@bar.com', status: 'offline'},//Note the keys are strings, not integers
'2': {email: 'foo@bar.com', status: 'offline'}
}
var log = [{id: 1, loggedIn: False, ActiveTime: '1hr'}]
//Then you can just do:
for (var i=0; i<log.length; i++){
log[i].status=users[log[i].id].status
}
这可能仍然不是“现实世界”的解决方案,因为我们倾向于将所有这些信息保存在数据库中,并使用JOIN操作将所有这些信息收集在一起。