Какой самый эффективный способ преобразовать массив объектов в объект с уникальными ключами - PullRequest
0 голосов
/ 10 мая 2019

Я пытаюсь найти наиболее эффективный способ 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]);
}

Ответы [ 3 ]

0 голосов
/ 10 мая 2019

вы можете использовать более элегантный способ сделать это, используя функцию уменьшения массива

// # 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": [ { "имя": "Грег", "год": "2000" }, { "имя": "нед", "год": "2000" }, { "имя": "пам", "год": "2000" } ], "2002": [ { "имя": "джон", "год": "2002" } ], "2005": [ { "имя": "боб", "год": "2005" } ] } }

0 голосов
/ 10 мая 2019

Это может быть так просто, как 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();
0 голосов
/ 10 мая 2019
Петля

A 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' } ] }
*/
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...