同时对 JavaScript 中的数据进行分组和转换(使用 Lodash)
Simultaneously grouping and transforming data in JavaScript (with Lodash)
给定以下数据集:
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 表示法,但我可以想象上述解决方案在大型集合上的性能非常糟糕。有什么改进建议吗?
您实际上并不需要 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)
给定以下数据集:
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 表示法,但我可以想象上述解决方案在大型集合上的性能非常糟糕。有什么改进建议吗?
您实际上并不需要 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)