How does the inventory comparison function work?

I am surprised no one figured out that inventory.sunglasses >= item[1] works the same way as inventory[item[0]] >= item[1]. My questions are:

  1. Can the former be used in place of the original to avoid this popular confusion?
  2. In my opinion, I think the original code was a sleek way to ‘match’ the inventory with the order by using similar notation such as ‘item’. I say this because when the “sunglasses” doesn’t match between the order and inventory, the bash terminal logs a different information.
    Am I right, or is there something I need to know?

So, instead of creating a new topic, I decided to ask my question under this one because it arose when I tried it out on VScode. The program itself works fine, it’s the exporting of modules that I tried to play around with and it broke. I thought I had understood exporting because I learned it today on codecademy modules topic:

module.exports = {checkInventory}
const {checkInventory} = require(’./library.js’);

These were the import and export statements used for this program.

When i tried other methods like inline exporting, export defaults etc, and used the different import statements, they didn’t work. Instead I got an error message ("Cannot use import statement outside a module). Why can I only use this method to export checkinventory?

Please post a link to this exercise. Members are reminded that when posting a new topic, or in a topic without a link, to please include one. Thanks.

Thanks a lot @tensor2, i was having the same problem but now it is solved by seeing your explanation.

I think the reason being, we running the program on Node.js.

i.e. when you want to run the program you just type

node app.js

so it’s running inside Node. And we studied in Modules chapter than for Node.js, only the module.export works.

https://www.codecademy.com/courses/introduction-to-javascript/lessons/modules/exercises/require

https://www.codecademy.com/courses/introduction-to-javascript/lessons/modules/exercises/export-default

  • Node.js doesn’t support export default by default, so module.exports is usually used for Node.js development and ES6 syntax is used for front-end development.

Above, element 0 is compared to element 1

This is incorrect. item Element 0 is not being compared to item element 1.

This entry in the inventory with the name given in item element 0 is being compared to item element 1.

Remember, order is an array where each entry is itself an array of a product and a quantity.
So inside the line,
order.every(item => (item => inventory[item[0]] >= item[1]);
the item is an array something like [‘sunglasses’, 5]

So when it compares inventory[item[0]] >= item[1]);, the instruction becomes - in the example I just gave - inventory['sunglasses'] >= 5.

Which, obviously, is then checking to see if there are 5 sunglasses left in the inventory, and returning success if there are.

4 Likes

No because then it would only work for .sunglasses.

1 Like

I think simpler way to explain this as follows:
let order = [[‘sunglasses’, 1], [‘bag’, 1]];
order.every(item = > …) equals to ‘[‘sunglasses’, 1], [‘bag’, 1]’, items of ‘order’ array: two items.
item[0] equals to ‘sunglasses’, ‘bag’ (first elements of the inner arrays of ‘order’ array), as .every() is iterating all elements in ‘order’ array.
item[1] equals to ‘1’, ‘1’, second element in the inner array or ‘order’ array.
So, inventory[item[0]] equls the values of the properties of the object cause it changes every time when .every() iterates.

3 Likes

I think what’s confusing is that one might have forgotten that there are two ways to get a property value from an object. To find the value associated with the property sunglasses in the object inventory, we could use the dot operator; inventory.sunglasses returns the value 1900. But the brackets method works just as well; operator[‘sunglasses’] also returns the value 1900.

Given the line:
order.every(item => (inventory[item[0]] >= item[1]);

As explained elsewhere above, the index item points to each member of the array order, one at a time, as the .every iterator cycles thru the array. Now, each member of order is itself an array of two members. Therefore, during the first iteration item points to ['sunglasses, 2] , and item[0] has the value ‘sunglasses’, and item[1], the value of 2.

Thus the statement : inventory[item[0]] >= item[1],

  1. evaluates inventory[‘sunglasses’] and returns 1990, then
  2. compares that value with item[1], which is 2, and
  3. returns a value of true

On the second iteration, item points to the next member of the arrayorder: item[0] is now ‘bags’, and item[1] is 1. The result of the logic operator >= is again true, and the .every iterator, having cycled over the entire array order, returns a value of true

14 Likes

Thank you so much for this clear explanation :smiley:

indeed we forgot some of the lessons we saw previously regarding all the theorical concept but now it’s makes more sense!

1 Like

Great explanation. I completely forget about the bracket method after much use of the dot operator of late. Thanks again for offering clarity. :white_check_mark:

1 Like

I think I finally understand, because of your explanation.
Especially your explanation of why using the same index position of inventory[item[0]] can remain the same but pertain to a different item or property of the inventory object with each iteration by the every() method.
Well put! Thank you!

This really helped!!!

For me tha original code needs to incorporate the comment(// true) at the end of line.
let inStock = order.every(item => inventory[item[0]] >= item[1]); //true

because, as in my case, if you rewrite the line as:

let inStock = order.every(item => { inventory[item[0]] >= item[1]} ) ; //false
the outcome will be false, because in this case you need to add a return statement as:

let inStock = order.every(item => {return inventory[item[0]] >= item[1]} ) ; //true

that arrow function feature is disappointing for me because is error prone.

let inStoclk = order.every( item => inventory[item[0]] >= item[1]`) ≈ let inStock =
inventory[‘sunglasses’] >= 2 && inventory[‘bags’] >= 1

inventory[‘sunglasses’] >= 2 = true
inventory[‘bags’] >= 1 = true

const inventory = { sunglasses: 817, pants: 236 }; const checkInventory = (order) => { order.items.forEach(item => { console.log('inventory '+item[0]+'= '+inventory[item[0]]); console.log('order '+ item[0]+'= '+item[1]) }) }; const order = { items: [['sunglasses', 3], ['pants', 2]], }; checkInventory(order);

the string “order.items” forces the program to approach the “inventory” object as an array.

about the post above
the string “order.items” in the “checkInventory” variable initializes “let item=key, value” in the “order” object. On the first pass of the “forEach” loop, it will be “sunglasses, 3” => “item = sunglasses, 3”. When accessing the “item” array in the “order=>item[1] = 3” object. When accessing the object “inventory => inventory[item[0]] = inventory.sunglasses = 817”.

Here is how I visualize the line of code to help me understand.

let inStock = order.every(item => inventory[item[0]] >= item[1]);

The order function takes an array. Consider this array for example

const item = [‘sunglasses’, 1];

console.log(item[0]) //prints sunglasses
console.log(item[1]) //prints 1

Now here is one way we can access the value of objects. Remember objects are key-value pairs.

const inventory = {
sunglasses: 1900,
pants: 1088,
bags: 1344
};

console.log(inventory[‘sunglasses’]); //prints 1900;

so if we were to pass our item array as an argument to the order function here is how it will behave

inventory[item[0]] >= item[1]; //item[0] = sunglasses and item[1] = 1
//replacing this gives
inventory[‘sunglasses’] >= 1; //remeber inventory[‘sunglasses’] holds a value of 1900
//this makes it
1900 > 1; //which evaluates to true;

Finally

What helped me to understand " inventory[item[0]] >= item[1]) " was understanding what are Computed Property Names - aka “bracket notation”.

In my understanding the “bracket notation” is a way to reach for a dinamic object key and get its value. In short, you search for a key inside of the object, find it and get it’s value, all at once.
Hence “inventory[item[0]]” actually meaning “1900” in the first iteration (because it’s the value of inventory.sunglasses) and actually meaning “1344” in the second iteration (because it’s the value of inventory.bags)

Disclaimer, I’m a beginner front-end dev. in a very early stage of my learning journey.