2013-01-15 123 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); 
});