[英]Extract specific values from multidimensional array javascript
I have a multidimensional array seen below. 我在下面看到一个多维数组。 I wish extract all the ingredients
values from it, and then do an action with them, like count how many of each there are. 我希望从中提取所有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 }
];
I have done this using a function from Underscore.js, _.flatten()
, and the vanilla javascript function map()
, but I had to use map()
twice. 我使用_.flatten()
, _.flatten()
和香草javascript函数map()
来完成此操作,但是我不得不两次使用map()
。 Once for extracting all the ingredients, and then to make a hash style structure that counts up the number of times each ingredient occurs. 一次提取所有成分,然后创建一个哈希样式结构,该结构计算每种成分出现的次数。 I store these counts in a separate object, ingredientCount
in this case. 我这些计数存储在一个单独的对象, ingredientCount
在这种情况下。
var ingredientCount = {};
_.flatten(products.map(function(x) {
return x.ingredients;
})).map(function(y){
return ingredientCount[y] = (ingredientCount[y] || 0) + 1;
});
console.log(ingredientCount);
will output the following list: 将输出以下列表:
{ 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 }
I have solved my problem, but I feel like there should be a cleaner, more efficient way to do this without using map()
twice. 我已经解决了我的问题,但是我觉得应该有一种更干净,更有效的方法来执行此操作,而无需两次使用map()
。 Can anyone help me out? 谁能帮我吗? I apologize in advance if this is a duplicate question. 如果这是一个重复的问题,我提前致歉。
This is the most elegant way I can think of in plain JavaScript, as it doesn't use any intermediary data structures (the original solution creates two arrays which are then combined into the final object). 这是我在普通JavaScript中可以想到的最优雅的方法,因为它不使用任何中间数据结构(原始解决方案创建了两个数组,然后将它们组合成最终对象)。
var counts = products.reduce(function (result, product) {
product.ingredients.forEach(function (ingredient) {
result[ingredient] = (result[ingredient] || 0) + 1;
});
return result;
}, {});
You could use recursion: 您可以使用递归:
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>
EDIT: No i'm not serious. 编辑:不,我不认真。 But its almost 3x faster 但是它快了将近3倍
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.