Go One Primitive Lower
Big unknown → smaller unknown → known primitive. Implement cart → addItem → find existing item → loop → compare ids. Missing foundations are routed to arrays, iteration and functions — only what is needed — and then you return to the cart.
"Implement a cart" is too big to start. "Loop through an array" is not. The move between them is recursive: split the unknown into smaller unknowns until one of them is something you already know how to write, and that is where you start.
The button that says "I still don't understand how to implement this" does one thing: it makes the thing smaller. addItem → Find Item → Loop Through Array → Compare IDs. At some rung you already know what to type, and that rung is the start.
The walk down goes Unknown → Unknown → Known Primitive, and where "Known" begins is different for every learner. Find your boundary, build upward from it, and stop treating someone else's boundary as the depth you owe the problem.
"I don't understand what `items.find()` does" is not a cart problem. It is four small things — arrays, iteration, callbacks, return values — and the fix is to learn exactly those, with the cart as the reason, then come back. Stacking another abstraction on top is the one thing that never works.
A cart needs functions, conditionals and arrays; a map is an alternative to the array, not a prerequisite; objects are how an entry is shaped. Drawing what depends on what tells you which foundation to learn first and which ones the cart does not need at all.
If the learner needs a cart, do not hand them a data structures course. An array, a map to compare it with, a loop, a conditional and a function are the whole bill — and then the cart. The rest arrives with the concept that needs it, which is when it will stick.