我有一系列物品:
const arr = [
{ id: 'abc', value: 2 },
{ id: 'def', value: 3 },
];
我想通过id
创建一个物品对象:
const obj = {
abc: { id: 'abc', value: 2 },
def: { id: 'def', value: 3 },
};
据我所知,最高效,最简洁的方法是通过Array.prototype.reduce
const obj = arr.reduce((obj, entry) => {
obj[entry.id] = entry;
return obj;
}, {});
是否有性能更高和更简洁的操作方法?他们是什么?
我知道这是相对主观的,因此我乐意接受一些建议,让我可以更好地表达问题。谢谢。
答案 0 :(得分:3)
您可以使用comma operator将其设置为单线:
const arr = [
{ id: 'abc', value: 2 },
{ id: 'def', value: 3 },
];
const obj = arr.reduce((obj, entry) => (obj[entry.id] = entry, obj), {});
console.log(obj);
可读性较差,但更为简洁。是否值得,取决于您。既然您提到您对spread感兴趣,这就是该解决方案,但是请参见下文以了解性能:
const arr = [
{ id: 'abc', value: 2 },
{ id: 'def', value: 3 },
];
const obj = arr.reduce((obj, entry) => ({ ...obj, [entry.id]: entry }), {});
console.log(obj);
另一种使用通过Object.assign
进行参数扩展的解决方案,但是这段代码对我来说有点笨拙,有关性能,请参见下文:
const arr = [
{ id: 'abc', value: 2 },
{ id: 'def', value: 3 },
];
const obj = Object.assign({}, ...arr.map(a => ({ [a.id]: a })));
console.log(obj);
对于性能最高的解决方案,很难克服for
循环:
const arr = [
{ id: 'abc', value: 2 },
{ id: 'def', value: 3 },
];
const obj = {}, len = arr.length;
for(let i = 0; i < len; i++) {
let a = arr[i];
obj[a.id] = a;
}
console.log(obj);
在我的计算机上进行的快速基准测试得出以下结果(在Firefox 66上):
test case | ops/s | result
reduce-comma | 22,248,622 ±2.83% | 6.89% slower
reduce-spread | 4,149,590 ±2.84% | 82.63% slower
object-assign | 1,809,170 ±0.69% | 92.43% slower
for-loop | 23,895,193 ±2.51% | fastest
第二个解决方案由于使用对象散布运算符而变得慢得多,该操作会在每次迭代时克隆对象。老实说,我不确定为什么Object.assign
会更慢,因为大多数对象传播的实现都只是Object.assign
的掩饰。
最后两个选项之间的区别是 miniscule ,但在优化效果欠佳的旧版浏览器中,差异可能更大。如果这确实是对性能至关重要的应用程序,我建议您运行自己的基准测试。