vaibhav deep
vaibhav deep

Reputation: 845

Append property from two arrays of objects

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

Answers (4)

charlietfl
charlietfl

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

Ariel
Ariel

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

sschwei1
sschwei1

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

ikhvjs
ikhvjs

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

Related Questions