2013-01-15 78 views
1

我想更好地学习JS看到次项目的数量增加值。使用underscore.js基于阵列

我有下面的代码,我试图投入underscore.js但我失败了。

我希望你能指出我要去哪里错了。

我试图采取一个循环,我知道的作品,然后用下划线capabilites来完善它。最上面的测试显示了循环,第二个测试是我试图用underscore.js做同样的事情。我失败了!

感谢

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); 
    }); 
+0

所以嗯...什么你的问题是什么呢? – asawyer

+0

@asawyer更新后,对不起 – Jon

+0

这一刻我没有时间讨论这个问题,但作为一个附注,'map(function(x){return x.ingredients;})'与'pluck('成分') – asawyer

回答

3

您减少是不是很实用。看看它的documentation!该“备忘录”,也称为“蓄电池”,是从以前的迭代中返回的值 - 这应该是你的ingredientCount地图。

var ingredientCount = _.chain(products) 
    .pluck("ingredients") // don't use map for that 
    .flatten() 
    .reduce(function (memo, item) { 
     memo[item] = (memo[item] || 0)+1; 
     /* alternative: 
     if (item in memo) 
      memo[item]++; 
     else 
      memo[item] = 1; 
     */ 
     return memo; // to be used in the next iteration! 
    }, {/*"{ingredient name}": 0*/}) 
    .value(); 

请注意memo === ingredientCount

+2

使用'_(产品).chain()'... 或者你会得到 'TypeError:Object function (a){return new j(a)}没有方法'chain'' –

+0

@DavidWest:这似乎已经在版本1.2.4中发生了变化,请查看[current docs](http://underscorejs.org) /#chaining) – Bergi

+0

谢谢,Bergi。 Koan跑步者使用下划线版本1.1.6。 –

0

我会用易于理解的代码,虽然它不是功能:

it("should count the ingredient occurrence (functional)", function() { 

    var ingredientCount = { "{ingredient name}": 0 }; 

    var dummy = _(products).chain() 
    .pluck("ingredients") 
    .flatten() 
    .each(function(x) { ingredientCount[x] = (ingredientCount[x] || 0) + 1; }) 
    .value(); 

    expect(ingredientCount['mushrooms']).toBe(2); 
});