Javascript reduce(),传入初值
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() 来确定每种成分出现的次数。
当我使用下面的代码时,成分计数 returns 未定义值:
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;
returns 循环的下一次迭代用作备忘录的数字。
改为
memo[x] = (memo[x] || 0) + 1;
return memo;
如果您真的想在一条语句中做到这一点
return memo[x] = (memo[x] || 0) + 1, memo;
我会在下划线中这样做
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>
看到一个普通的 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 }
];
我正在尝试使用 map()、flatten() 和 reduce() 来确定每种成分出现的次数。
当我使用下面的代码时,成分计数 returns 未定义值:
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;
returns 循环的下一次迭代用作备忘录的数字。
改为
memo[x] = (memo[x] || 0) + 1;
return memo;
如果您真的想在一条语句中做到这一点
return memo[x] = (memo[x] || 0) + 1, memo;
我会在下划线中这样做
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>
看到一个普通的 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)));