[英]Javascript reduce(), passing in initial value
我正在使用下划线库完成一项练习,以对项目出现次数进行计数。
具体来说,我有这个数组:
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 = {“ {成分名称}”:0};
_(products).chain()
.map(function(obj) {return obj.ingredients;})
.flatten().reduce(function(memo, x) {
return ingredientCount[x] = (ingredientCount[x] || 0) + 1;
})
.value();
有人可以帮忙解释为什么会这样吗?
谢谢!
return memo[x] = (memo[x] || 0) + 1;
返回一个数字,供循环的下一个迭代用作备忘录。
代替做
memo[x] = (memo[x] || 0) + 1;
return memo;
如果您真的想在单个语句中执行此操作
return memo[x] = (memo[x] || 0) + 1, memo;
看到一个普通的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)));
我会这样强调
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>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.