簡體   English   中英

用唯一鍵將對象數組轉換為對象的最有效方法是什么

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM