我正在使用下划线库进行练习,以执行项目出现次数。
具体来说,我有这个数组:
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 }
];
我正在尝试使用map(),flatten()和reduce()来确定每种成分出现的次数。
当我使用下面的代码时,ingredientCount返回未定义的值:
var ingredientCount = { "{ingredient name}": 0 };
_(products).chain()
.map(function(obj) {return obj.ingredients;})
.flatten().reduce(function(memo, x) {
return memo[x] = (memo[x] || 0) + 1;
}, ingredientCount)
.value();
但是,如果我删除第二个参数reduce()并在函数体中包含初始对象,那么一切都按预期工作,即:
var ingredientCount = {“{ingredient name}”:0};
_(products).chain()
.map(function(obj) {return obj.ingredients;})
.flatten().reduce(function(memo, x) {
return ingredientCount[x] = (ingredientCount[x] || 0) + 1;
})
.value();
有人可以帮助解释为什么会这样吗?
谢谢!
答案 0 :(得分:2)
return memo[x] = (memo[x] || 0) + 1;
返回循环的下一次迭代的数字以用作备忘录。
代替
memo[x] = (memo[x] || 0) + 1;
return memo;
如果你真的想要在一个声明中
return memo[x] = (memo[x] || 0) + 1, memo;
答案 1 :(得分:1)
看到简单的JS替代方案总是很有趣:
var counts = p.reduce(function(acc, prod) {
prod.ingredients.forEach(function(i) {
acc[i] = (acc[i] || 0) + 1;
});
return acc;
},{});
看起来更清楚,但在一般情况下使用起来更好:
if (!acc.hasOwnProperty(i)) acc[i] = 0;
acc[i]++
对应部分。
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 }
];
function countIngredients(p) {
var counts = p.reduce(function(acc, prod) {
prod.ingredients.forEach(function(i) {
acc[i] = (acc[i] || 0) +1;
})
return acc;
},{})
return counts;
}
document.write(JSON.stringify(countIngredients(products)));

答案 2 :(得分:0)
我会在下划线中这样做
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 }
];
ingredientCount = {};
_(products).chain()
.map(function(obj) {return obj.ingredients;}).flatten().each(function(memo, x) {
ingredientCount[memo] = (ingredientCount[memo] || 0) + 1;
});
document.write(JSON.stringify(ingredientCount));
//this will produce this "{"artichoke":1,"sundried tomatoes":2,"mushrooms":2,"roma":1,"goats cheese":1,"rosemary":1,"black beans":1,"jalapenos":1,"blue cheese":1,"garlic":1,"walnuts":1,"spinach":1,"kalamata olives":1,"sesame seeds":1}"
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore.js"></script>