链接数组方法(filter、map、reduce),而不是使用双循环



我遇到了一个无法解决的问题。。。这就是我要做的。

给定以下对象数组,

products = [
{ name: 'Sonoma', ingredients: ['artichoke', 'sundried tomatoes', 'mushrooms'], containsNuts: false },
{ name: 'Pizza Primavera', ingredients: ['roma', 'sundried tomatoes', 'goats cheese', 'rosemary'], containsNuts: false },
{ name: 'South Of The Border', ingredients: ['black beans', 'jalapenos', 'mushrooms'], containsNuts: false },
{ name: 'Blue Moon', ingredients: ['blue cheese', 'garlic', 'walnuts'], containsNuts: true },
{ name: 'Taste Of Athens', ingredients: ['spinach', 'kalamata olives', 'sesame seeds'], containsNuts: true },
];

我知道我可以通过嵌套循环来添加成分名称的键,然后在循环计数时增加值,如下所示:

let ingredientCount = {}; 
for (i = 0; i < products.length; i += 1) {
for (j = 0; j < products[i].ingredients.length; j += 1) { //loop ingredients 
ingredientCount[products[i].ingredients[j]] = (ingredientCount[products[i].ingredients[j]] || 0) + 1; 
}
}

因此,ingredientCount应该类似于:{朝鲜蓟":1蘑菇"2}***

这里的问题是,我需要使用map和reduce来创建与上面相同的结果。

let ingredientCount = {}
ingredientCount = 
products.filter ((value) => {
// filter out arrays within ingredients 
// so out come should be like  
/* 
[ingredients: ['artichoke', 'sundried tomatoes', 'mushrooms']
,ingredients: ['roma', 'sundried tomatoes', 'goats cheese', 'rosemary']
,ingredients: ['black beans', 'jalapenos', 'mushrooms']
,ingredients: ['blue cheese', 'garlic', 'walnuts']
,ingredients: ['spinach', 'kalamata olives', 'sesame seeds']
*/
}).map ((value) => {
/* then take out ingredients and map this array to  
arthichoke: ['artichoke','artichoke','artichoke']
sundried tomatoes: ['sundried tomatoes']
etc... 
*/

}).reduce((acc, value) => {
/* then reduce arrays within each key to numbers. 
hence, the output should be 
artichokes: artichokes.length (i.e. 3 )
sundried toamatoes: 1

*/
})

我是否可以使用上面的数组方法来获得完全相同的结果,而不必使用循环?

提前谢谢。

您需要使用map()flat(),然后使用reduce()。函数flat()使数组变平。

products = [
{ name: 'Sonoma', ingredients: ['artichoke', 'sundried tomatoes', 'mushrooms'], containsNuts: false },
{ name: 'Pizza Primavera', ingredients: ['roma', 'sundried tomatoes', 'goats cheese', 'rosemary'], containsNuts: false },
{ name: 'South Of The Border', ingredients: ['black beans', 'jalapenos', 'mushrooms'], containsNuts: false },
{ name: 'Blue Moon', ingredients: ['blue cheese', 'garlic', 'walnuts'], containsNuts: true },
{ name: 'Taste Of Athens', ingredients: ['spinach', 'kalamata olives', 'sesame seeds'], containsNuts: true },
];
let obj = products
.map(p => p.ingredients)
.flat()
.reduce((obj, val) => {
obj[val] = (obj[val] || 0) + 1;
return obj;
}, {});
console.log(obj);

使用数组的.reduce方法和.forEach方法的解决方案。

var products = [
{ name: 'Sonoma', ingredients: ['artichoke', 'sundried tomatoes', 'mushrooms'], containsNuts: false },
{ name: 'Pizza Primavera', ingredients: ['roma', 'sundried tomatoes', 'goats cheese', 'rosemary'], containsNuts: false },
{ name: 'South Of The Border', ingredients: ['black beans', 'jalapenos', 'mushrooms'], containsNuts: false },
{ name: 'Blue Moon', ingredients: ['blue cheese', 'garlic', 'walnuts'], containsNuts: true },
{ name: 'Taste Of Athens', ingredients: ['spinach', 'kalamata olives', 'sesame seeds'], containsNuts: true },
];
var result = products.reduce((acc,obj) => 
{obj.ingredients.forEach(ob=> acc[ob] = acc[ob]+1 || 1)
return acc;
},{});
console.log(result);

您可以使用两个forEachmap,并维护一个只需要更新的最终数组。

let products = [
{ name: 'Sonoma', ingredients: ['artichoke', 'sundried tomatoes', 'mushrooms'], containsNuts: false },
{ name: 'Pizza Primavera', ingredients: ['roma', 'sundried tomatoes', 'goats cheese', 'rosemary'], containsNuts: false },
{ name: 'South Of The Border', ingredients: ['black beans', 'jalapenos', 'mushrooms'], containsNuts: false },
{ name: 'Blue Moon', ingredients: ['blue cheese', 'garlic', 'walnuts'], containsNuts: true },
{ name: 'Taste Of Athens', ingredients: ['spinach', 'kalamata olives', 'sesame seeds'], containsNuts: true },
];
let iCount = {};
products.forEach((c) => c.ingredients.forEach((i) => iCount.hasOwnProperty(i) ? iCount[i]++ : iCount[i] = 1));
console.log(iCount);

使用Array.prototype.reduce来减少数组并在执行过程中增加计数。

const products = [{
name: 'Sonoma',
ingredients: ['artichoke', 'sundried tomatoes', 'mushrooms'],
containsNuts: false
},
{
name: 'Pizza Primavera',
ingredients: ['roma', 'sundried tomatoes', 'goats cheese', 'rosemary'],
containsNuts: false
},
{
name: 'South Of The Border',
ingredients: ['black beans', 'jalapenos', 'mushrooms'],
containsNuts: false
},
{
name: 'Blue Moon',
ingredients: ['blue cheese', 'garlic', 'walnuts'],
containsNuts: true
},
{
name: 'Taste Of Athens',
ingredients: ['spinach', 'kalamata olives', 'sesame seeds'],
containsNuts: true
},
];
const result = products.reduce((acc, { ingredients }) => {
ingredients.forEach((ingredient) => {
acc[ingredient] = (acc[ingredient] || 0) + 1;
});
return acc;
}, Object.create(null));
console.log(result);

使用flatMapreduce。(除??,操作员外(

const products = [
{ name: 'Sonoma', ingredients: ['artichoke', 'sundried tomatoes', 'mushrooms'], containsNuts: false },
{ name: 'Pizza Primavera', ingredients: ['roma', 'sundried tomatoes', 'goats cheese', 'rosemary'], containsNuts: false },
{ name: 'South Of The Border', ingredients: ['black beans', 'jalapenos', 'mushrooms'], containsNuts: false },
{ name: 'Blue Moon', ingredients: ['blue cheese', 'garlic', 'walnuts'], containsNuts: true },
{ name: 'Taste Of Athens', ingredients: ['spinach', 'kalamata olives', 'sesame seeds'], containsNuts: true },
];
const ingredientCount = products
.flatMap(({ ingredients }) => ingredients)
.reduce((acc, item) => ((acc[item] = (acc[item] ?? 0) + 1), acc), {});
console.log(ingredientCount);

最新更新