Here I have 3 arrays,
- orderdIds: It contains all ordersIds
- associatedUsers: It contains all associated users to the orders.
- users: It contains all user details.
Now I have to SET the user’s data into the associatedUsers variable. So how can I do that in a single loop? Here I try with multiple loops below
const orderIds = [101, 102];
const associatedUsers = [{ orderId: 101, userIds: [1, 2] }, { orderId: 102, userIds: [2] }];
const users = [{ userId: 1, email: 'email1' }, { userId: 2, email: 'email2' }];
associatedUsers.map((user) => {
user.userIds.map((u, index) => {
const userIndex = users.findIndex((use) => { return u === use.userId; });
console.log(userIndex)
if (userIndex > -1) {
user.userIds[index] = users[userIndex]
}
})
});
console.log(associatedUsers);
2
Answers
What you need to do is fundamentally an operation that requires nested iterations. Talking it through in English, what you have to do is: For each "associated user", iterate through the
userIds
and find the matching user. So the nested loop is the only real way to go.There is a way to decrease the computational complexity by an order of magnitude, though, from
O(n * m)
(n
: total number ofuserIds
in all arrays,m
: total number of users) toO(m) + O(n)
. Turn theusers
array into an object indexed byuserId
first, and then you’ll be able to avoid the.findIndex
and just look up the ID on the object.First we create a user map, which allows us to find a user by his id, without needing to loop through the whole users array every time we do so.
Then for every association we create a users array and for each userId value we get the user from the map and add it to the users array.
As such, this works in one for loop, but technically it’s still 2 loops since inside the for loop we have the
.map
which loops throughassocitaion.userIds
.It can’t be simplified nor optimized further.