Я пытаюсь использовать метод reduce на массиве объектов, каждый из которых является человеком и ароматом мороженого, которое им нравится. Цель состоит в том, чтобы уменьшить этот массив до одного объекта, который содержит ароматы как свойства и общее количество раз, когда аромат указан как значения.
данные:
const data = [
{ name: 'Tyler', favoriteIceCreams: ['Strawberry', 'Vanilla', 'Chocolate', 'Cookies & Cream'] },
{ name: 'Richard', favoriteIceCreams: ['Cookies & Cream', 'Mint Chocolate Chip', 'Chocolate', 'Vanilla'] },
{ name: 'Amanda', favoriteIceCreams: ['Chocolate', 'Rocky Road', 'Pistachio', 'Banana'] },
{ name: 'Andrew', favoriteIceCreams: ['Vanilla', 'Chocolate', 'Mint Chocolate Chip'] },
{ name: 'David', favoriteIceCreams: ['Vanilla', 'French Vanilla', 'Vanilla Bean', 'Strawberry'] },
{ name: 'Karl', favoriteIceCreams: ['Strawberry', 'Chocolate', 'Mint Chocolate Chip'] }
];
Это то, что у меня есть до сих пор, но я честно не знаю, как это сделать.
let iceCreamTotals = {
Strawberry: 0,
Vanilla: 0,
Chocolate: 0,
CookiesCream: 0,
MintChocolateChip: 0,
RockyRoad: 0,
Pistachio: 0,
Banana: 0,
FrenchVanilla: 0,
VanillaBean: 0
}
data.reduce((total, current) => {
return iceCreamTotals
}, 0)
Вы можете собирать имена ароматов и подсчитывать их по ходу дела. Следующее создает объект со свойствами, которые являются ароматами в данных с подсчетом того, сколько раз они происходят.
var data = [
{ name: 'Tyler', favoriteIceCreams: ['Strawberry', 'Vanilla', 'Chocolate', 'Cookies & Cream'] },
{ name: 'Richard', favoriteIceCreams: ['Cookies & Cream', 'Mint Chocolate Chip', 'Chocolate', 'Vanilla'] },
{ name: 'Amanda', favoriteIceCreams: ['Chocolate', 'Rocky Road', 'Pistachio', 'Banana'] },
{ name: 'Andrew', favoriteIceCreams: ['Vanilla', 'Chocolate', 'Mint Chocolate Chip'] },
{ name: 'David', favoriteIceCreams: ['Vanilla', 'French Vanilla', 'Vanilla Bean', 'Strawberry'] },
{ name: 'Karl', favoriteIceCreams: ['Strawberry', 'Chocolate', 'Mint Chocolate Chip'] }
];
var flavours = data.reduce(function(acc, obj) {
// for each flavour, add it to the accumulator if it not already there
// and increament its count
obj.favoriteIceCreams.forEach(function(flavour) {
if (!acc[flavour]) {
acc[flavour] = 0;
}
++acc[flavour];
});
return acc;
}, Object.create(null));
console.log(flavours);
reduce this array into a single object
, поэтому аккумулятор (второй аргумент для reduce
, необязательный) должен быть объектом. Затем на каждом шаге подсчитайте соответствующее свойство для каждого элемента массива (c.favoriteIceCreams.forEach
). p[cream] = (p[cream] || 0) + 1;
это просто синтаксический сахар для "добавить один, если он существует в противном случае, равным 0 + 1".
const data = [
{ name: 'Tyler', favoriteIceCreams: ['Strawberry', 'Vanilla', 'Chocolate', 'Cookies & Cream'] },
{ name: 'Richard', favoriteIceCreams: ['Cookies & Cream', 'Mint Chocolate Chip', 'Chocolate', 'Vanilla'] },
{ name: 'Amanda', favoriteIceCreams: ['Chocolate', 'Rocky Road', 'Pistachio', 'Banana'] },
{ name: 'Andrew', favoriteIceCreams: ['Vanilla', 'Chocolate', 'Mint Chocolate Chip'] },
{ name: 'David', favoriteIceCreams: ['Vanilla', 'French Vanilla', 'Vanilla Bean', 'Strawberry'] },
{ name: 'Karl', favoriteIceCreams: ['Strawberry', 'Chocolate', 'Mint Chocolate Chip'] }
];
console.log(data.reduce((p, c) => {
c.favoriteIceCreams.forEach(cream => {
p[cream] = (p[cream] || 0) + 1;
});
return p;
}, {}));
Ваша проблема имеет два аспекта. Первый собирает все вкусы со всех людей. Второй - подсчет частоты каждого аромата. Ваш код будет проще и легче отлаживать и более читабельным, если вы выделите эти два аспекта. Собирать все вкусы просто
const flavors = [].concat(...data.map(({favoriteIceCreams}) => favoriteIceCreams));
Или, если вы предпочитаете:
const flavors = [];
for (const {favoriteIceCreams} of data) flavors.push(...favoriteIceCreams);
На SO есть много решений о подсчете частоты появления в массиве. Подумайте об этом.
Вы можете использовать for..of
loop, Object.hasOwnProperty()
чтобы проверить, установлено ли свойство на объекте, если значение истинного инкремента, иначе заданное значение равно 0
let res = {}
for (let {favoriteIceCreams} of data)
for (let iceCream of favoriteIceCreams)
res[iceCream] = res.hasOwnProperty(iceCream) ? ++res[iceCream] : 1;
(p[cream] || 0) + 1
до++p[cream] || 1
, но это может быть немного запутанным.~~p[cream] + 1
:)