我有一个多维数组,如下所示。我希望从中提取所有ingredients
值,然后对它们执行操作,例如计算每个值的数量。
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 }
];
我使用Underscore.js,_.flatten()
和vanilla javascript函数map()
中的函数完成了此操作,但我必须使用map()
两次。一旦提取所有成分,然后制作哈希样式结构,计算每个成分发生的次数。我将这些计数存储在一个单独的对象中,在这种情况下为ingredientCount
。
var ingredientCount = {};
_.flatten(products.map(function(x) {
return x.ingredients;
})).map(function(y){
return ingredientCount[y] = (ingredientCount[y] || 0) + 1;
});
console.log(ingredientCount);
将输出以下列表:
{ 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 }
我已经解决了我的问题,但我觉得应该有一种更干净,更有效的方法来做到这一点,而不使用map()
两次。谁能帮我吗?如果这是一个重复的问题,我会提前道歉。
答案 0 :(得分:1)
这是我在普通JavaScript中可以想到的最优雅的方式,因为它没有使用任何中间数据结构(原始解决方案创建了两个数组,然后将它们组合到最终对象中)。
var counts = products.reduce(function (result, product) {
product.ingredients.forEach(function (ingredient) {
result[ingredient] = (result[ingredient] || 0) + 1;
});
return result;
}, {});
答案 1 :(得分:0)
你可以使用递归:
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 }
];
// written by hand, with <3
function ic(p,o,i,b,g) {
i|=0;g|=0;
if(!b&&p&&!p.ingredients)
while((g=ic(p[g].ingredients,o,0,g+1))&&p[g]);
else {
o[p[i]]=(o[p[i]]|0)+1;
return p[i+1]?ic(p,o,i+1,b):b;
}
}
var ingredientCount = {};
ic(products, ingredientCount);
document.body.innerHTML = JSON.stringify(ingredientCount).replace(/(\,)/g,"$1<br/>");
body {font-family: monospace }
<body></body>
编辑:不,我不认真。 But its almost 3x faster 强>