I am trying to learn JS better.
I have the below code which I am trying to put into underscore.js but am failing.
I’m hoping you can point out where I’m going wrong.
I’m trying to take a loop that I know works and then use underscores capabilites to refine it. The top test shows the loops, the second test is my attempt to do the same with underscore.js. I’m failing miserably!
Thanks
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 }
];
it("should count the ingredient occurrence (imperative)", function () {
var ingredientCount = { "{ingredient name}": 0 };
for (i = 0; i < products.length; i+=1) {
for (j = 0; j < products[i].ingredients.length; j+=1) {
ingredientCount[products[i].ingredients[j]] = (ingredientCount[products[i].ingredients[j]] || 0) + 1;
}
}
expect(ingredientCount['mushrooms']).toBe(2);
});
it("should count the ingredient occurrence (functional)", function () {
var ingredientCount = { "{ingredient name}": 0 };
var ffd = _(products).chain()
.map(function(x){return x.ingredients;})
.flatten()
.reduce(function(memo,x){
if (x===memo)
{
return ingredientCount[memo] = ingredientCount[memo]+1;
}
else
{
return ingredientCount[memo] = 0;
}
})
.value();
/* chain() together map(), flatten() and reduce() */
expect(ingredientCount['mushrooms']).toBe(2);
});
Your reduce is not very functional. Have a look at its documentation! The “memo”, also know as “accumulator”, is the value returned from the previous iteration – that should be your
ingredientCountmap.Notice that
memo === ingredientCount!