简体   繁体   English

如何将值从数组中的对象添加到另一个数组中的另一个对象?

[英]How to add value from object in an array into another object in another array?

I'm trying to add object value from one array into another object in another array 我试图将对象值从一个数组添加到另一个数组中的另一个对象

first array structure is: 第一个数组结构是:

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

the expected result is to be something like this: 预期结果将是这样的:

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

You'll want to map over the second array and merge the two objects together, where the emails are the same. 您将需要映射到第二个数组,并将两个对象合并在一起,其中电子邮件是相同的。 Therefore you can use Array.map and Object.assign: 因此,您可以使用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)
  })
}

You can use Map and map , Map will makes searching values from array1 faster as compared to find 您可以使用Mapmap ,与find相比, Map可以更快地从array1搜索值

 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)) 

Try to use foreach and find method: 尝试使用foreachfind方法:

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);

If you want to check whether the status has value: 如果要检查状态是否有价值:

array2.forEach(f=>{
    const emailStatus = array1.find(a1 => a1.email == f.email);
    if (emailStatus && emailStatus.status)
        f.status = emailStatus.status;
});

I'm writing this with the assumption that you're learning Javascript, so keep in mind it's not meant to be a definitive 'best way' answer, but rather to illustrate how you can approach the problem using aspects of the language you likely already know. 我在写这篇文章时是假设您正在学习Javascript,因此请记住,这并不是确定的“最佳方法”答案,而是为了说明您如何使用可能已经存在的语言方面解决问题。知道。

It looks like array1 is basically your user database with current status. 看起来array1是具有当前状态的用户数据库。 So you need to iterate through array2 and copy the properties from the corresponding object in array1 . 因此,您需要遍历array2并复制array1相应对象的属性。

There are a number of ways to approach this problem. 有很多方法可以解决此问题。 The most naive way would be: 最幼稚的方式是:

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

However, there are a number of problems with this: 但是,这有很多问题:

  • It's very difficult to follow the nested for loops, and it's not very efficient. 遵循嵌套的for循环非常困难,而且效率也不高。
  • You're trying to create a NEW array of NEW objects that represents the union of the objects in the two arrays. 您正在尝试创建一个NEW对象的NEW数组,该数组表示两个数组中对象的并集。 This means you have to create a new array AND a new set of objects. 这意味着您必须创建一个新的数组和一组新的对象。 This is really inefficient and confusing. 这确实是低效且令人困惑的。
  • To that same point, "copying an object" is a tricky subject. 同样,“复制对象”是一个棘手的主题。 The tempObj = array2[i] bit doesn't work as you might think, because it just assigns tempObj a reference to the existing object; tempObj = array2[i]位不起作用,因为它只是为tempObj分配了现有对象的引用 that is, making changes to tempObj will affect array2[i] as well. 也就是说,对tempObj进行更改也会影响array2[i]

Instead, let's do some optimizations: 相反,让我们做一些优化:

  • Create a hash table from array to avoid loops and simplify looking up the primary user object (or just use an Object with emails as keys to begin with). array创建哈希表,以避免循环并简化查找主要用户对象的过程(或仅使用带有电子邮件的对象作为键)。
  • Add properties to the objects already in array2 向已经在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

This is a lot easier to read an a bit more efficient. 这更容易阅读,效率更高。 If you're stuck with the arrays as the data structure for this information, I don't know how to do much better. 如果您坚持使用数组作为此信息的数据结构,那么我不知道如何做得更好。

However, if you have control over how these structures are created, you could choose something much more efficient. 但是,如果您可以控制如何创建这些结构,则可以选择效率更高的方法。 Instead of an array of objects, you could create an object to serve as a user 'database' and use a common, unique identifier to correlate the user data with data in the log: 您可以创建一个对象来充当用户“数据库”,而不是使用对象数组,并使用一个通用的唯一标识符将用户数据与日志中的数据相关联:

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
}

This is probably still not a 'real-world' solution, as we would tend to keep all of this information in a database and use a JOIN operation to pull all of this information together. 这可能仍然不是一个“现实世界”的解决方案,因为我们倾向于将所有这些信息保留在数据库中,并使用JOIN操作将所有这些信息汇总在一起。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM