Reputation: 845
In JavaScript, I have two arrays - arr1
, arr2
arr1
is an array of objects as shown below -
[
{ user: {id: 1, name: "name1", role: "A"} },
{ user: {id: 2, name: "name2", role: "B"} },
{ user: {id: 3, name: "name3", role: "A"} }
]
arr2
is also an array of objects :
[
{ id: 2, username: "brad", ... },
{ id: 1, username: "colly", ... },
{ id: 3, username: "sophie", ... }
]
Now, what I want to get an output arr1
like this -
[
{ user: {id: 1, name: "name1", role: "A", username: "colly"} },
{ user: {id: 2, name: "name2", role: "B", username: "brad"} },
{ user: {id: 3, name: "name3", role: "A", username: "sophie"} }
]
Basically, if arr1[0].user.id = arr2[1].id
then add the username
property from arr2
to that user
with the id
. Same across the entire array, and then finally return the original array arr1
with username
appended to each respective user
object.
Hope you understand what I tried to explain. Thanks in advance.
Upvotes: 0
Views: 704
Reputation: 171690
The most efficient way that only iterates each array once is to map arr2 to an object or Map with id
as keys then loop over arr1 and look each id up to get the username.
An object or Map lookup is an o(1) operation whereas methods like find() require numerous iterations of arr2
const arr1=[{user:{id:1,name:"name1",role:"A"}},{user:{id:2,name:"name2",role:"B"}},{user:{id:3,name:"name3",role:"A"}}],
arr2=[{id:2,username:"brad"},{id:1,username:"colly"},{id:3,username:"sophie"}];
const arr2Names = new Map(arr2.map(e => [e.id, e.username]));
arr1.forEach(({user}) => user.username = arr2Names.get(user.id))
console.log(arr1)
Upvotes: 2
Reputation: 1436
Given your two arrays, you will need to do this:
// loop through all the elements in arr1
const result = arr1.map(element => {
// Search the element by ID in arr2 (You need to loop every time, probably not the better solution.
// Maybe better with a Map
const elInArr2Found = arr2.find(arr2Element => arr2Element.id === element.user.id);
// If the element is found, set the property "username" to the element
// If the element is not found, leave it as is
if (elInArr2Found !== undefined) {
element.user.username = elInArr2Found.username;
}
// return the element
return element;
})
result will have all your elements with the username set.
Check the Map documentation to this avoid nested loop.
Upvotes: 0
Reputation: 393
This should do the trick:
const arr1 = [
{ user: {id: 1, name: "name1", role: "A"} },
{ user: {id: 2, name: "name2", role: "B"} },
{ user: {id: 3, name: "name3", role: "A"} }
];
const arr2 = [
{ id: 2, username: "brad", ... },
{ id: 1, username: "colly", ... },
{ id: 3, username: "sophie", ... }
]
mergedArray = arr1.map(e => {
return {
user: {
...e.user,
username: arr2.find(x => x.id === e.user.id).username
}
}
})
In case you want to merge more values than just the username, you can save the value found in arr2 in a variable:
mergedArray = arr1.map(e => {
const match = arr2.find(x => x.id === e.user.id);
return {
user: {
...e.user,
username: match.username,
someOtherValue: match.someOtherValue
}
}
})
If it is not certain, that objects in arr2, contain a username, you will get an error when accessing the username in the function, username: match?.username ?? 'fallbackValue'
will prevent the error and return a default value in case, if no default value is needed, you can leave the ?? '...'
part
Upvotes: 0
Reputation: 5977
You can use map
and find
in your case.
const arr1 = [
{ user: { id: 1, name: "name1", role: "A" } },
{ user: { id: 2, name: "name2", role: "B" } },
{ user: { id: 3, name: "name3", role: "A" } },
];
const arr2 = [
{ id: 2, username: "brad" },
{ id: 1, username: "colly" },
{ id: 3, username: "sophie" },
];
const output = arr1.map(el => ({
user: { ...el.user, username: arr2.find(x => x.id === el.user.id).username },
}));
console.log(output);
Upvotes: 0