[英]What is the most performant way to convert an Array of Object to an Object with unique keys
我試圖找出最高性能的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]);
}
您可以通過使用數組的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”:[{“名稱”:“鮑勃”,“年份”:“ 2005”}}}}
它可能就像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();
在大多數情況下,像您這樣的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' } ] }
*/
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.