Подсчитайте количество элементов в каждой категории в объекте JavaScript

У меня есть массив, содержащий несколько сотен объектов, каждый из которых имеет категорию. Я хочу вернуть объект, в котором перечислены категории с подсчетом количества элементов для каждой категории.

const arr = [
    {id: 1, name: 'ford', category: 'vehicle'},
    {id: 2, name: 'pig', category: 'animal'},
    {id: 3, name: 'dog', category: 'animal'},
    {id: 4, name: 'chev', category: 'vehicle'},
    {id: 5, name: 'cat', category: 'animal'},
    {id: 6, name: 'jeep', category: 'vehicle'},
    {id: 7, name: 'honda', category: 'vehicle'}
]

Как мне пройтись по объекту и создать новый объект, содержащий только две категории и сколько из них в каждой категории?

Желаемый результат:

{vehicle: 4, animal: 3}

Код:

const arr = [
    {id: 1, name: 'ford', category: 'vehicle'},
    {id: 2, name: 'pig', category: 'animal'},
    {id: 3, name: 'dog', category: 'animal'},
    {id: 4, name: 'chev', category: 'vehicle'},
    {id: 5, name: 'cat', category: 'animal'},
    {id: 6, name: 'jeep', category: 'vehicle'},
    {id: 7, name: 'honda', category: 'vehicle'}
]

const final = {};
arr.forEach((v) => {
  const tst = v.category;
  console.info(tst);
  if (tst in final){
     console.info('found one');
  }
});

//console.info(final);
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
Раскрытие чувствительных данных
Раскрытие чувствительных данных
Все внешние компоненты, рассмотренные здесь до сих пор, взаимодействуют с клиентской стороной. Однако, если они подвергаются атаке, они не...
Зод: сила проверки и преобразования данных
Зод: сила проверки и преобразования данных
Сегодня я хочу познакомить вас с библиотекой Zod и раскрыть некоторые ее особенности, например, возможности валидации и трансформации данных, а также...
Эпизод 23/17: Twitter Space о будущем Angular, Tiny Conf
Эпизод 23/17: Twitter Space о будущем Angular, Tiny Conf
Мы провели Twitter Space, обсудив несколько проблем, связанных с последними дополнениями в Angular. Также прошла Angular Tiny Conf с 25 докладами.
Руководство ChatGPT по продаже мини JS-файлов
Руководство ChatGPT по продаже мини JS-файлов
JS-файл - это файл, содержащий код JavaScript. JavaScript - это язык программирования, который в основном используется для добавления интерактивности...
4
0
1 072
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

У вас есть правильное представление о цикле по массиву и проверке того, встречалась ли уже категория. Чего вам не хватает, так это инициализировать счетчик, когда вы находите новую категорию, и увеличивать его при следующем обнаружении этой категории:

const arr = [
    {id: 1, name: 'ford', category: 'vehicle'},
    {id: 2, name: 'pig', category: 'animal'},
    {id: 3, name: 'dog', category: 'animal'},
    {id: 4, name: 'chev', category: 'vehicle'},
    {id: 5, name: 'cat', category: 'animal'},
    {id: 6, name: 'jeep', category: 'vehicle'},
    {id: 7, name: 'honda', category: 'vehicle'}
]

const final = {};
arr.forEach((v) => {
  const cat = v.category;
  if (cat in final) {
     final[cat]++;
  } else {
     final[cat] = 1;
  }
});

console.info(final);
Ответ принят как подходящий

Вы можете использовать уменьшить

const arr = [
    {id: 1, name: 'ford', category: 'vehicle'},
    {id: 2, name: 'pig', category: 'animal'},
    {id: 3, name: 'dog', category: 'animal'},
    {id: 4, name: 'chev', category: 'vehicle'},
    {id: 5, name: 'cat', category: 'animal'},
    {id: 6, name: 'jeep', category: 'vehicle'},
    {id: 7, name: 'honda', category: 'vehicle'}
]


const categories = arr.reduce((acc, cur) => {
   acc[cur.category] = (acc[cur.category] || 0) + 1
   return acc;
}, {})

console.info(categories)

редактировать: Теперь, через год, я бы написал это так

const arr = [
    {id: 1, name: 'ford', category: 'vehicle'},
    {id: 2, name: 'pig', category: 'animal'},
    {id: 3, name: 'dog', category: 'animal'},
    {id: 4, name: 'chev', category: 'vehicle'},
    {id: 5, name: 'cat', category: 'animal'},
    {id: 6, name: 'jeep', category: 'vehicle'},
    {id: 7, name: 'honda', category: 'vehicle'}
]


const categories = arr.reduce((acc, cur) => Object.assign(acc, {
  [cur.category]:  (acc[cur.category] || 0) + 1, 
}), {})

console.info(categories)

Похоже, что category будет существовать всегда, поэтому вам нужно проверять не то, существует ли он, а то, что в нем содержится; возьмите то, что он содержит, и увеличьте это свойство объекта final:

const arr = [
    {id: 1, name: 'ford', category: 'vehicle'},
    {id: 2, name: 'pig', category: 'animal'},
    {id: 3, name: 'dog', category: 'animal'},
    {id: 4, name: 'chev', category: 'vehicle'},
    {id: 5, name: 'cat', category: 'animal'},
    {id: 6, name: 'jeep', category: 'vehicle'},
    {id: 7, name: 'honda', category: 'vehicle'}
]

const final = {};
for (const { category } of arr) {
  final[category] = (final[category] || 0) + 1;
};
console.info(final);

const arr = [
  { id: 1, name: 'ford', category: 'vehicle' },
  { id: 2, name: 'pig', category: 'animal' },
  { id: 3, name: 'dog', category: 'animal' },
  { id: 4, name: 'chev', category: 'vehicle' },
  { id: 5, name: 'cat', category: 'animal' },
  { id: 6, name: 'jeep', category: 'vehicle' },
  { id: 7, name: 'honda', category: 'vehicle' },
]

// this will hold the results
const result = {}

for (const item of arr) {
  // we have not encountered such category before
  if (result[item.category] === undefined) {
    // setting this category to 1
    result[item.category] = 1
    
  // we encountered such category before
  } else { 
    // addint +1 to it
    result[item.category] += 1
  }
}

console.info(result)

Другие вопросы по теме