Одновременная группировка и преобразование данных в JavaScript (с помощью Lodash) - PullRequest
0 голосов
/ 22 декабря 2018

Учитывая следующий набор данных:

const users = {
  "1": { id: "1", name: "Alex" },
  "2": { id: "2", name: "John" },
  "3": { id: "3", name: "Paul" }
};

const memberships = [
  { userId: "1", groupId: "1" },
  { userId: "2", groupId: "2" },
  { userId: "3", groupId: "1" }
];

Какой эффективный способ достижения следующего желаемого результата?

const usersByGroupId = {
  "1": [{ id: "1", name: "Alex" }, { id: "3", name: "Paul" }],
  "2": [{ id: "2", name: "John" }]
}

Я придумал следующее (используя Lodash):

const usersByGroupId = mapValues(
  groupBy(memberships, "groupId"),
  memberships => memberships.map(membership => users[membership.userId])
);

Я не очень хорошо знаком с обозначениями больших О, но могу представить, что производительность вышеупомянутого решения довольно велика на больших наборах.Есть предложения по улучшению?

1 Ответ

0 голосов
/ 22 декабря 2018

Вам действительно не нужен lodash - вы можете сделать это за один шаг с reduce().Просто проверьте, существует ли ключ, если да, нажмите, если нет, установите новый массив и нажмите.Для этого требуется только одна итерация массива membership и для каждого поиска в объекте users (который является более или менее постоянным временем), что делает эту операцию линейной по времени.

const users = {"1": { id: "1", name: "Alex" },"2": { id: "2", name: "John" },"3": { id: "3", name: "Paul" }};
const memberships = [{ userId: "1", groupId: "1" },{ userId: "2", groupId: "2" },{ userId: "3", groupId: "1" }];

let groups = memberships.reduce((obj, {userId, groupId}) => {
    (obj[groupId] || (obj[groupId] = []) ).push(users[userId])
    return obj
}, {})

console.log(groups)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...