简体   繁体   中英

Making a count object by initializing properties from iterating through elements in an array

Alright, so I'm working on the final problem of javascript-koans. The code and dataset I'm given are as follows:

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();
});

I think I understand some of what's going on: We're iterating through the products array to iterate through the ingredients array of each product, taking an ingredient, and using bracket notation to call it as a property from the ingredientCount object. But around here is where I'm losing it, because then we set it equal to itself or zero, then add one regardless. Can someone correct me on what I have wrong there and explain what I'm missing? How/where does calling the ingredientCount variable with 'mushrooms' in bracket notation establish 'mushrooms' in this expression? And how are we incrementing the ingredientCount's {ingredient name} property without explicitly referencing it? Is there some kind of implicit assignment or something going on?

Also, the test runner returns an error letting me know the expected result should be 2.

I figured it out. I was right in my written summation of that code, except what we're looking at in this code isn't just an expression, more importantly it's a variable assignment. So on each iteration through each ingredient of each product we're initializing a new property in the ingredientCount object and setting it equal to itself or zero. But why do that? Because if you set a non-existent object's property equal to itself you get undefined--it doesn't initialize. Luckily, undefined is a falsey value , and so if the property is non-existent it instead gets initialized by being set to zero, then incremented to one. After that each additional count for each existing ingredient takes the truthy numerical value (skipping the zero after the or) and adds one. So when we look at the result from the console, we see the ingredientCount object isn't behaving like a function (as I was confused in thinking it had been), instead it's a simple object with properties that we can access to give us their individual counts:

[object Object] {
  artichoke: 1,
  black beans: 1,
  blue cheese: 1,
  garlic: 1,
  goats cheese: 1,
  jalapenos: 1,
  kalamata olives: 1,
  mushrooms: 2,
  roma: 1,
  rosemary: 1,
  sesame seeds: 1,
  spinach: 1,
  sundried tomatoes: 2,
  walnuts: 1
  {ingredient name}: 0
}

{ingredient name} was just in the code as a placeholder, which is why it shows up there at the bottom.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM