如何使用Underscore.js的reduce方法生成甜点类型统计对象
问题:使用Underscore.js的reduce方法统计各类型甜点的数量
给定如下甜点数组:
var desserts = [ { name: 'Chocolate Cake', ingredients: ['cocoa', 'flour', 'sugar', 'eggs', 'milk', 'butter' ], type: 'cake' }, { name: 'Snickerdoodles', ingredients: ['flour', 'milk', 'butter', 'eggs', 'sugar', 'cinnamon', 'cream of tartar'], type: 'cookie' }, { name: 'Strawberry-Rhubarb Pie', ingredients: ['flour', 'water', 'eggs', 'sugar', 'strawberries', 'rhubarb'], type: 'pie' }, { name: 'Lemonade', ingredients: ['water', 'sugar', 'lemons'], type: 'drink' }, { name: 'Chocolate Chip Cookies', ingredients: ['flour', 'butter', 'sugar', 'eggs', 'chocolate chips'], type: 'cookie' }, { name: 'Apple Pie', ingredients: ['flour', 'water', 'cinnamon', 'apples', 'sugar'], type: 'pie' }, { name: 'Apple Pie', ingredients: ['flour', 'water', 'cinnamon', 'apples', 'sugar'], type: 'pie' }, { name: 'Angel Food Cake', ingredients: ['flour', 'eggs', 'sugar', 'cream of tartar'], type: 'cake' } ];
需求是用Underscore.js的reduce方法生成统计各类型甜点数量的对象,示例输出:
{'pie': 3, 'cake': 2, 'cookie': 2, 'drink': 1}
当前实现代码:
var dessertCategories = function (desserts) { return _.reduce(desserts, function(memo, dessert) { var type1 = dessert.type; if (memo[type1] === undefined) { memo[type1] = 1; } else { memo[type1]++; } return memo; }, {}); };
怀疑代码存在逻辑或使用方式错误,请求排查修正。
解答
你的代码逻辑本身是正确的,运行后能得到预期的统计结果。不过可以按照Underscore.js的风格做更简洁的优化,让代码更紧凑:
var dessertCategories = function(desserts) { return _.reduce(desserts, function(memo, dessert) { // 利用逻辑或运算符简化判断,若memo中无该类型则初始化为0,再加1 memo[dessert.type] = (memo[dessert.type] || 0) + 1; return memo; }, {}); };
说明
- 原代码的
if-else判断可以用(memo[dessert.type] || 0)替代:当memo[dessert.type]为undefined(即该类型首次出现)时,||会返回0,之后加1就完成了初始化;如果已有值,则直接加1。 - 无需额外定义
type1变量,直接使用dessert.type即可,减少冗余。 - 这个写法完全符合Underscore.js的
reduce使用规范,memo作为累加器每次迭代后返回,最终得到统计对象。
运行优化后的代码,会输出预期结果:
{ cake: 2, cookie: 2, pie: 3, drink: 1 }
内容的提问来源于stack exchange,提问作者boshao13
相关产品推荐
相关产品推荐

