我正在尝试找到一种优雅且有效的方法来将对象数组转换为由键索引的对象(在本例中为“groupByThisKey”)。我相信它被称为 HashMap 。
我能够想出一个原始版本
用下面的一些数据进行解释:
const arr = [
{
id: 1,
name: "one",
groupByThisKey: 'groupA'
},
{
id: 2,
name: "two",
groupByThisKey: 'groupB'
},
{
id: 3,
name: "three",
groupByThisKey: 'groupB'
},
{
id: 4,
name: "four",
groupByThisKey: 'groupA'
}
];
const groupedByKey = {};
arr.map(obj => {
if (groupedByKey[obj.groupByThisKey])
groupedByKey[obj.groupByThisKey].push(obj)
else
groupedByKey[obj.groupByThisKey] = [obj]
});
console.log(groupedByKey)
它确实给出了所需的输出:
{
groupA: [
{
id: 1,
name: "one",
groupByThisKey: 'groupA'
},
{
id: 4,
name: "four",
groupByThisKey: 'groupA'
}
],
groupB: [
{
id: 2,
name: "two",
groupByThisKey: 'groupB'
},
{
id: 3,
name: "three",
groupByThisKey: 'groupB'
}
]
}
但以一种相当原始的方式。我更愿意使用更短、更现代的方法来执行此操作,如果可能的话,可能使用 object.assign 或 reduce,但无法理解它,因为我需要每个键都有一个值数组。
我找到了许多示例,这些示例似乎都适用于每个键只有一个值的用例,但就我而言,我需要一个按该键分组的对象数组,所以我找到的例子只会采用最新的。这是一个例子:
const hash = Object.assign({}, ...array.map(s => ({[s.key]: s.value})));
最佳答案
你实现的东西非常正确,让我使用 reducer 消除副作用:
const arr = [
{
id: 1,
name: "one",
groupByThisKey: 'groupA'
},
{
id: 2,
name: "two",
groupByThisKey: 'groupB'
},
{
id: 3,
name: "three",
groupByThisKey: 'groupB'
},
{
id: 4,
name: "four",
groupByThisKey: 'groupA'
}
];
console.log(arr.reduce((groupedByKey,obj) => {
if (groupedByKey[obj.groupByThisKey])
groupedByKey[obj.groupByThisKey].push(obj)
else
groupedByKey[obj.groupByThisKey] = [obj]
return groupedByKey;
}, {}));
这里你可以用最 fp 的方式来写它。并不是真正的性能,下面的下一个版本(在此之后)将具有更好的性能,因为它不是在每次迭代中创建对象或数组。
const arr = [
{
id: 1,
name: "one",
groupByThisKey: 'groupA'
},
{
id: 2,
name: "two",
groupByThisKey: 'groupB'
},
{
id: 3,
name: "three",
groupByThisKey: 'groupB'
},
{
id: 4,
name: "four",
groupByThisKey: 'groupA'
}
];
console.log(arr.reduce(
(groups, x) =>
({
...groups,
[x.groupByThisKey]: [
...(groups[x.groupByThisKey] || []),
x
]
})
, {}
))
与上面具有相同逻辑的更简单版本:
const arr = [
{
id: 1,
name: "one",
groupByThisKey: 'groupA'
},
{
id: 2,
name: "two",
groupByThisKey: 'groupB'
},
{
id: 3,
name: "three",
groupByThisKey: 'groupB'
},
{
id: 4,
name: "four",
groupByThisKey: 'groupA'
}
];
console.log(arr.reduce(
(groups, x) => {
let key = x.groupByThisKey;
if (groups[key] === undefined)
groups[key] = [];
groups[key].push(x);
return groups;
}, {}
))
关于javascript - ES2015+ 有效地将对象数组转换为以对象数组作为值的分组 HashMap 的方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55799551/