我正在尝试找出最高性能的JavaScript方法,将对象数组转换为具有唯一键的对象和将对象填充为值的数组。
例如:
const array = [
{ "name": "greg", "year": "2000" },
{ "name": "john", "year": "2002" },
{ "name": "bob", "year": "2005" },
{ "name": "ned", "year": "2000" },
{ "name": "pam", "year": "2000" },
];
我希望将其转换为:
{
"2000": [
{ "name": "greg", "year": "2000" },
{ "name": "ned", "year": "2000" },
{ "name": "pam", "year": "2000" }
],
"2002": [ { "name": "john", "year": "2002" } ],
"2005": [ { "name": "bob", "year": "2005" } ],
}
到目前为止,这是我到目前为止所做的:
let yearsObj = {};
for (let i=0; i<array.length; i++) {
if (!yearsObj[array[i].year]) {
yearsObj[array[i].year] = [];
}
yearsObj[array[i].year].push(array[i]);
}
答案 0 :(得分:-1)
通过使用数组的reduce函数,您可以使用更优雅的方法来实现
// # impl
const group = key => array =>
array.reduce(
(objectsByKeyValue, obj) => ({
...objectsByKeyValue,
[obj[key]]: (objectsByKeyValue[obj[key]] || []).concat(obj)
}),
{}
);
// # usage
console.log(
JSON.stringify({
byYear: group(array),
}, null, 1)
);
//输出
VM278:1 { “ carsByBrand”:{ “ 2000”:[ { “ name”:“ greg”, “ year”:“ 2000” }, { “ name”:“ ned”, “ year”:“ 2000” }, { “ name”:“ pam”, “ year”:“ 2000” } ], “ 2002”:[ { “ name”:“ john”, “ year”:“ 2002” } ], “ 2005”:[ { “ name”:“ bob”, “ year”:“ 2005” } ] } }
答案 1 :(得分:-1)
即使Object.fromEntries(array.map(obj => [obj.year,obj]))
并不是您真正需要的东西,它也可以这么简单,但是谈论性能却比所有建议的都要慢,因此我举一个糟糕的例子来说明简短声明并非总是最快的。
您的方式似乎是最快的性能。
运行下面的代码片段以查看实际时间。
// common
let array = [
{ "name": "greg", "year": "2000" },
{ "name": "john", "year": "2002" },
{ "name": "bob", "year": "2005" },
{ "name": "ned", "year": "2000" },
{ "name": "pam", "year": "2000" },
];
// simple as a statement way
console.time();
console.log(Object.fromEntries(array.map(obj => [obj.year,obj])));
console.timeEnd();
// using .reduce way
console.time();
const result = array.reduce((prev, curr) => {
const { year } = curr;
if (prev[year]) {
prev[year].push(curr);
} else {
prev[year] = [curr];
}
return prev;
}, {});
console.log(result);
console.timeEnd();
// your way
console.time();
let yearsObj = {};
for (let i=0; i<array.length; i++) {
if (!yearsObj[array[i].year]) {
yearsObj[array[i].year] = [];
}
yearsObj[array[i].year].push(array[i]);
}
console.log(yearsObj);
console.timeEnd();
答案 2 :(得分:-2)
像for
这样的循环(命令式)在大多数情况下可能是最快的。但是,在这种情况下,您不太可能看到很大的不同。可以改善示例中代码的一件事是在for
循环之前获取数组长度并将其分配给变量,这样就不会在循环的每次迭代中都对其进行计算。
const yearsObj = {};
const arrayLength = array.length; // Only calculate array length once
for (let i=0; i<arrayLength; i++) {
if (!yearsObj[array[i].year]) {
yearsObj[array[i].year] = [];
}
yearsObj[array[i].year].push(array[i]);
}
在这种情况下,我更喜欢使用Array.reduce()
。它更具可读性,并且性能差异可以忽略不计。
const arr = [
{ name: 'greg', year: '2000' },
{ name: 'john', year: '2002' },
{ name: 'bob', year: '2005' },
{ name: 'ned', year: '2000' },
{ name: 'pam', year: '2000' },
];
const result = arr.reduce((prev, curr) => {
const { year } = curr;
if (prev[year]) {
prev[year].push(curr);
} else {
prev[year] = [curr];
}
return prev;
}, {});
/* Result:
{ '2000':
[ { name: 'greg', year: '2000' },
{ name: 'ned', year: '2000' },
{ name: 'pam', year: '2000' } ],
'2002': [ { name: 'john', year: '2002' } ],
'2005': [ { name: 'bob', year: '2005' } ] }
*/