Reputation: 485
I'm trying to add object value from one array into another object in another array
first array structure is:
var array1 = [
{ email: '[email protected]', status: 'offline' },
{ email: '[email protected]', status: 'online' },
{ email: '[email protected]', status: 'idle' }
]
var array2 = [
{ email: '[email protected]', status: '', activeTime: '1hr', logedIn: true, },
{ email: '[email protected]', status: '', activeTime: '1hr', logedIn: true, },
{ email: '[email protected]', status: '', activeTime: '1hr', logedIn: true, },
{ email: '[email protected]', status: '', activeTime: '2hr', logedIn: false, },
{ email: '[email protected]', status: '', activeTime: '2hr', logedIn: false, },
{ email: '[email protected]', status: '', activeTime: '2hr', logedIn: false, },
{ email: '[email protected]', status: '', activeTime: '2hr', logedIn: false, },
{ email: '[email protected]', status: '', activeTime: '1.5hr', logedIn: true, },
]
the expected result is to be something like this:
var arrayJoined = [
{ email: '[email protected]', status: 'offline', activeTime: '1hr', logedIn: true, },
{ email: '[email protected]', status: 'offline', activeTime: '1hr', logedIn: true, },
{ email: '[email protected]', status: 'offline', activeTime: '1hr', logedIn: true, },
{ email: '[email protected]', status: 'online', activeTime: '2hr', logedIn: false, },
{ email: '[email protected]', status: 'online', activeTime: '2hr', logedIn: false, },
{ email: '[email protected]', status: 'online', activeTime: '2hr', logedIn: false, },
{ email: '[email protected]', status: 'online', activeTime: '2hr', logedIn: false, },
{ email: '[email protected]', status: 'idle', activeTime: '1.5hr', logedIn: true, },
]
Upvotes: 1
Views: 77
Reputation: 445
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.
It looks like array1
is basically your user database with current status. So you need to iterate through array2
and copy the properties from the corresponding object in 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:
for
loops, and it's not very efficient.tempObj = array2[i]
bit doesn't work as you might think, because it just assigns tempObj
areference to the existing object; that is, making changes to tempObj
will affect array2[i]
as well.Instead, let's do some optimizations:
array
to avoid loops and simplify looking up the primary user object (or just use an Object with emails as keys to begin with). array2
var arr1hash = {};
for (var i=0; i<array1.length; i++){
arr1hash[array[i].email] = i;
}
// {'[email protected]': 1, '[email protected]: 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: '[email protected]', status: 'offline'},//Note the keys are strings, not integers
'2': {email: '[email protected]', 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.
Upvotes: 0
Reputation: 38134
Try to use foreach
and find
method:
var array1 = [
{ email: '[email protected]', status: 'offline' },
{ email: '[email protected]', status: 'online' },
{ email: '[email protected]', status: 'idle' }
]
var array2 = [
{ email: '[email protected]', status: '', activeTime: '1hr', logedIn: true, },
{ email: '[email protected]', status: '', activeTime: '1hr', logedIn: true, },
{ email: '[email protected]', status: '', activeTime: '1hr', logedIn: true, },
{ email: '[email protected]', status: '', activeTime: '2hr', logedIn: false, },
{ email: '[email protected]', status: '', activeTime: '2hr', logedIn: false, },
{ email: '[email protected]', status: '', activeTime: '2hr', logedIn: false, },
{ email: '[email protected]', status: '', activeTime: '2hr', logedIn: false, },
{ email: '[email protected]', 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;
});
Upvotes: 1
Reputation: 37755
You can use Map
and map
, Map
will makes searching values from array1
faster as compared to find
let array1 = [{ email: '[email protected]', status: 'offline' },{ email: '[email protected]', status: 'online' },{ email: '[email protected]', status: 'idle' }]
let array2 = [{ email: '[email protected]', status: '', activeTime: '1hr', logedIn: true, },{ email: '[email protected]', status: '', activeTime: '1hr', logedIn: true, },{ email: '[email protected]', status: '', activeTime: '1hr', logedIn: true, },{ email: '[email protected]', status: '', activeTime: '2hr', logedIn: false, },{ email: '[email protected]', status: '', activeTime: '2hr', logedIn: false, },{ email: '[email protected]', status: '', activeTime: '2hr', logedIn: false, },{ email: '[email protected]', status: '', activeTime: '2hr', logedIn: false, },{ email: '[email protected]', 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))
Upvotes: 1
Reputation: 171
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:
function merge(array1, array2) {
return array2.map(obj => {
var matchingObj = array1.find(el => el.email === obj.email)
return Object.assign({}, obj, matchingObj)
})
}
Upvotes: 5