как из массива объектов получить новый объект?

Есть массив объектов пользоватилей

[{
  username: 'Alice',
  status: 'online',
  lastActivity: 10
}, {
  username: 'Lucy',
  status: 'offline',
  lastActivity: 22
}, {
  username: 'Bob',
  status: 'online',
  lastActivity: 104
}]

из него нужно получить новый объект в котором перечислено, кто из пользователей онлайн или оффлайн, или если lastActivity > 10, то статус away.

{
  online: ['Alice'],
  offline: ['Lucy'],
  away: ['Bob']
}

мой код работает не правильно, помогите разобраться

function whoIsOnline(friends) {
  if (!friends) {
    return {};
  }

  const newOb = {};

  for (const us in friends) {
    if (us.status === 'online' && us.lastActivity <= 10) {
      newOb.online = us.username;
    } else if (us.status === 'offline') {
      newOb.offline = us.username;
    } else if (us.lastActivity > 10) {
      newOb.away = us.username;
    }
  }

  return newOb;
}

// Получается вот:

expect(received).toMatchObject(expected)
- Expected  - 11
+ Received  +  1

- Object {
-   "away": Array [
-     "Bob",
-   ],
-   "offline": Array [
-     "Lucy",
-   ],
-   "online": Array [
-     "Alice",
-   ],
- }
+ Object {}


Ответы (1 шт):

Автор решения: vsemozhebuty

Попробуйте так:

const users = [{
  username: 'Alice',
  status: 'online',
  lastActivity: 10
}, {
  username: 'Lucy',
  status: 'offline',
  lastActivity: 22
}, {
  username: 'Bob1',
  status: 'online',
  lastActivity: 104
}, {
  username: 'Bob2',
  status: 'online',
  lastActivity: 105
}, {
  username: 'Bob3',
  status: 'online',
  lastActivity: 106
}];

const stats = users.reduce(
  (acc, { username, status, lastActivity }) => {
    if (status === 'online' && lastActivity > 10) status = 'away';
    acc[status] ??= [];
    acc[status].push(username);
    return acc;
  },
  {},
);

console.log(stats);

→ Ссылка