Reputation: 71
I have two arrays of object:
var user = [
{id: 1, name: 'David'},
{id: 2, name: 'John'},
{id: 3, name: 'Matt'},
]
var data = [
{id: 1, userId: 1, flower: 'Clover'},
{id: 2, userId: 1, flower: 'Sakura'},
{id: 3, userId: 2, flower: 'Rose'},
{id: 4, userId: 3, flower: 'Sunflower'},
]
and the output:
var result = [
{name: 'David', flower: 'Clover'},
{name: 'David', flower: 'Sakura'},
{name: 'Matt', flower: 'Sunflower'},
]
I still don't know how to join two tables with different name column for id. Did anyone know the simplest way to do that in javascript? Thanks before
Upvotes: 0
Views: 1111
Reputation: 519
As long as you aren't too concerned with performance, I'd recommend using lodash and creating a map of user id to user record for readability.
const { keyBy } = require('lodash');
const user = [
{id: 1, name: 'David'},
{id: 2, name: 'John'},
{id: 3, name: 'Matt'},
];
const data = [
{id: 1, userId: 1, flower: 'Clover'},
{id: 2, userId: 1, flower: 'Sakura'},
{id: 3, userId: 2, flower: 'Rose'},
{id: 4, userId: 3, flower: 'Sunflower'},
];
const userIdToUserMap = keyBy(user, 'id');
const result = data.map(dataItem => {
return {
name: userIdToUserMap[dataItem.userId].name,
flower: dataItem.flower
};
});
Lodash keyBy
reference: https://lodash.com/docs/4.17.15#keyBy
Javascript array .map()
reference: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map
If you prefer to avoid using lodash
, you can create the userIdToUserMap
as follows:
const userIdToUserMap = user.reduce((acc, cur) => {
acc[cur.id] = cur;
return acc;
}, {});
Javascript array .reduce()
reference: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce
Upvotes: 0
Reputation: 49
//Making an index of all users
var userIndex={}; user.forEach (el=>{ if (el && el.id) userIndex[el.id] = el });
//Fill the result with each data entry
var result = []; data.forEach (el=>{ if(el && el.userId && userIndex[el.userId]) result.push({ name:userIndex[el.userId].name, flower:el.flower }) });
//Check for results
result.forEach(el=>console.log(el));
Some additional verification is implemented here against a corrupted data and exceptions: what if an user element haven't an id
? Or, if a data entry haven't a userId
? That's why not so "clean".
Upvotes: 0
Reputation: 119
Multiple ways to do it as other suggested. This is another one
Edit: Little bit confused about your question, but from my understanding, should be
var result = data.map(dataObj=>{
return {
name:user.find(userObj=>{
return userObj.id === dataObj.userId
}).name,
flower:dataObj.flower
}
})
console.log(result)
You might want to clarify why
{ name:'John', flower:'Rose'}
is excluded.
But my code will include that in it. Like the result below
console.log(result)
[
{ name: 'David', flower: 'Clover' },
{ name: 'David', flower: 'Sakura' },
{ name: 'John', flower: 'Rose' },
{ name: 'Matt', flower: 'Sunflower' }
]
Upvotes: 1
Reputation: 154
var user = [
{id: 1, name: 'David'},
{id: 2, name: 'John'},
{id: 3, name: 'Matt'}
];
var data = [
{id: 1, userId: 1, flower: 'Clover'},
{id: 2, userId: 1, flower: 'Sakura'},
{id: 3, userId: 2, flower: 'Rose'},
{id: 4, userId: 3, flower: 'Sunflower'}
];
var results = [];
for (var x = 0; x < user.length; x++) {
for (var y = 0; y < data.length; y++) {
if (data[y].userId == user[x].id) {
var tmp = { name: user[x].name, flower: data[y].flower }
results.push(tmp);
}
}
}
console.log(results);
This can probably be done using filter and map, but I could only think of this for loop.
Upvotes: 0