同时在JavaScript中对数据进行分组和转换(使用Lodash)

时间:2018-12-22 03:29:00

标签: javascript arrays lodash relationship denormalization

给出以下数据集:

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])
);

我对大型O表示法并不熟悉,但是我可以想象上述解决方案的性能在大型集合上非常糟糕。有任何改进建议吗?

1 个答案:

答案 0 :(得分:1)

您实际上并不需要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)