1

I have two array of objects (users and deposits).

const users = [
    {
        _id: 1,
        username: 'tajmirul',
        email: '[email protected]',
    },
    {
        _id: 2,
        username: 'tajmirul2',
        email: '[email protected]',
    },
];

const deposits = [
    {
        _id: 1,
        userId: 1,
        amount: 250,
    },
    {
        _id: 2,
        userId: 1,
        amount: 500,
    },
];

I want to calculate total deposit for each user and update the users array. like this

// modified users array will look like this
[
    {
        _id: 1,
        username: 'tajmirul'
        deposit: 750,
    },
    {
        _id: 2,
        username: 'tajmirul2'
        deposit: 0,
    }
]

I tried this

users.forEach((user, index) => {
    deposits.forEach(deposit => {
        if (user._id === deposit.userId) {
            if (users[index].deposit) {
                users[index].deposit += deposit.amount;
            } else {
                users[index].deposit = deposit.amount;
            }
        }
    });
});

In this case, the time complexity is O(m * n). Is there any way to reduce the time complexity?

1
  • Are the arrays aligned? (i.e. are users[i] and deposits[i] always the for the same id?) If so, you only need a single const mapped = users.map((user, i) => /* combine user and deposits[i] */). Commented Aug 26, 2022 at 22:28

3 Answers 3

1

You can create a hash map and index deposits by user Ids.

This gives you O(m)

Size of Users = n, Size of Deposits = m

After that, you can iterate over users and that would be O(n)

In the end, the time complexity will be O(MAX(m,n))

const users = [
  {
    _id: 1,
    username: 'tajmirul',
    email: '[email protected]',
  },
  {
    _id: 2,
    username: 'tajmirul2',
    email: '[email protected]',
  },
];

const deposits = [
  {
    _id: 1,
    userId: 1,
    amount: 250,
  },
  {
    _id: 2,
    userId: 1,
    amount: 500,
  },
];


const depositsMap = new Map();

for (const deposit of deposits) { // O(m)
  if (depositsMap.has(deposit.userId)) {
    const prevDeposit = depositsMap.get(deposit.userId);
    depositsMap.set(deposit.userId, prevDeposit + deposit.amount);
  } else {
    depositsMap.set(deposit.userId, deposit.amount ?? 0);
  }
}

const aggregatedUsers = users.map(user => { // O(n)
  return {
    _id: user._id,
    username: user.username,
    deposit: depositsMap.get(user._id) ?? 0,
  };
});

console.log(aggregatedUsers);

Sign up to request clarification or add additional context in comments.

Comments

0
const usersWithAmount = users.map((user) => {
  const { _id } = user;
  const depositsFiltered = deposits.filter(({ userId }) => userId === _id);
  if (depositsFiltered.length > 0) {
    return {
      ...user,
      deposit:
        (user?.deposit ?? 0) +
        depositsFiltered.reduce((acc, { amount }) => (acc + amount), 0),
    };
  }
  return { ...user, amount: 0 };
});

3 Comments

I think time complexity is the same. O(m * n). Can you reduce the time complexity?
I'd say the only difference here is that map is faster than forEach
or do it from different side - deposits.map(... @TajmirulIslam
0

You might first reduce the deposits to {userId:total} which is say O(n),
then update the users which is O(m):

const users = [
    {
        _id: 1,
        username: 'tajmirul',
        email: '[email protected]',
    },
    {
        _id: 2,
        username: 'tajmirul2',
        email: '[email protected]',
    },
];

const deposits = [
    {
        _id: 1,
        userId: 1,
        amount: 250,
    },
    {
        _id: 2,
        userId: 1,
        amount: 500,
    },
];

const userDeposits = deposits.reduce((a, {userId, amount}) => (a[userId] = (a[userId] || 0) + amount, a), {}) // O(n)

users.forEach(u => u.amount = userDeposits[u._id] || 0) // O(m)

console.log(users)
.as-console-wrapper {
  top: 0;
  max-height: none !important;
  }

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.