skip to Main Content

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


  1. 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 of userIds in all arrays, m: total number of users) to O(m) + O(n). Turn the users array into an object indexed by userId first, and then you’ll be able to avoid the .findIndex and just look up the ID on the object.

    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' }];
    
    const usersById = Object.fromEntries(
      users.map(
        user => [user.userId, user]
      )
    );
    for (const aUser of associatedUsers) {
        aUser.userIds = aUser.userIds.map(id => usersById[id] ?? id);
    }
    
    console.log(associatedUsers);
    Login or Signup to reply.
  2. 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 through associtaion.userIds.

    It can’t be simplified nor optimized further.

    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' }];
    
    const userMap = new Map(users.map(user => [user.userId, user]));
    for (const association of associatedUsers) {
        association.users = association.userIds.map(userId => userMap.get(userId));
    }
    console.log(associatedUsers);
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search