DEV Community

Mohamed Idris
Mohamed Idris

Posted on

Choosing a Data Structure for a Shopping Cart (Array vs Object vs Map)

When building a shopping cart, you need to store items and update them (change quantity, remove item, etc.). You can do that with an array, an object, or a Map — but they don’t behave the same.


1) Using an Array

const cart = [
  { id: 1, name: "first", price: 10 },
  { id: 2, name: "second", price: 20 },
];
Enter fullscreen mode Exit fullscreen mode

Why it can be annoying

If you want to find or update an item by id, you usually need to loop:

const item = cart.find((p) => p.id === 2);
Enter fullscreen mode Exit fullscreen mode

That’s fine for small carts, but as the cart grows, repeated .find() / .filter() calls add extra work.


2) Using an Object

const cart = {
  "id-1": { id: 1, name: "first", price: 10 },
  "id-2": { id: 2, name: "second", price: 20 },
};
Enter fullscreen mode Exit fullscreen mode

Pros

  • Fast lookups by key:
cart["id-2"]; // { id: 2, name: "second", price: 20 }
Enter fullscreen mode Exit fullscreen mode

Downsides

  • Keys are basically strings only
  • You need to be careful with object edge-cases (prototype stuff) and iteration patterns

3) Using new Map() (Recommended for cart-like data)

A Map stores key → value pairs, like an object — but it’s designed for this use case.

Why Map is nice

  • Easy and clean lookups: map.get(id)
  • Safe iteration
  • Keys can be any type (number, object, etc.)
  • Built-in helpers: set, get, has, delete, size

Map Example: Shopping Cart

// create a new Map
const cart = new Map();

// add items
cart.set(1, { id: 1, name: "Apple", price: 0.5, quantity: 3 });
cart.set(2, { id: 2, name: "Banana", price: 0.3, quantity: 6 });
cart.set(3, { id: 3, name: "Orange", price: 0.4, quantity: 4 });

// read item
console.log(cart.get(1)); 
// { id: 1, name: 'Apple', price: 0.5, quantity: 3 }

// check existence
console.log(cart.has(99)); // false

// size
console.log(cart.size); // 3

// remove item
cart.delete(2);

// loop
for (const [id, item] of cart) {
  console.log(id, item.name, item.price, item.quantity);
}
Enter fullscreen mode Exit fullscreen mode

Converting Array → Map (and back)

Array of items

const items = [
  { id: 1, name: "first", price: 10 },
  { id: 2, name: "second", price: 20 },
];
Enter fullscreen mode Exit fullscreen mode

Convert to [key, value] pairs

const cartItems = items.map((item) => [item.id, item]);

console.log(cartItems);
// [
//   [1, { id: 1, name: 'first', price: 10 }],
//   [2, { id: 2, name: 'second', price: 20 }],
// ]
Enter fullscreen mode Exit fullscreen mode

Create a Map from pairs

const cart = new Map(cartItems);
Enter fullscreen mode Exit fullscreen mode

Convert Map back to array

const cartArray = Array.from(cart.entries());

console.log(cartArray);
// [
//   [1, { id: 1, name: 'first', price: 10 }],
//   [2, { id: 2, name: 'second', price: 20 }],
// ]
Enter fullscreen mode Exit fullscreen mode

Credits: John's Smilga's course

Top comments (4)

Collapse
 
edriso profile image
Mohamed Idris

Here’s a tiny “update quantity” example that shows why Map feels cleaner for a cart 👇

Update quantity with an Array (usually needs a lookup)

const cart = [
  { id: 1, name: "Apple", price: 0.5, qty: 3 },
  { id: 2, name: "Banana", price: 0.3, qty: 6 },
];

function updateQtyArray(id, qty) {
  const item = cart.find((p) => p.id === id);
  if (!item) return;
  item.qty = qty;
}

updateQtyArray(2, 10);
console.log(cart);
Enter fullscreen mode Exit fullscreen mode

Update quantity with a Map (direct by key)

const cart = new Map([
  [1, { id: 1, name: "Apple", price: 0.5, qty: 3 }],
  [2, { id: 2, name: "Banana", price: 0.3, qty: 6 }],
]);

function updateQtyMap(id, qty) {
  const item = cart.get(id);
  if (!item) return;
  cart.set(id, { ...item, qty }); // replace safely
}

updateQtyMap(2, 10);
console.log(cart.get(2));
Enter fullscreen mode Exit fullscreen mode

With Map, the id is the key, so updating is basically: get → set (no searching).

Collapse
 
edriso profile image
Mohamed Idris

One extra note about using plain objects for a cart 👇

Object edge-cases (prototype stuff)

Objects inherit from Object.prototype, so some keys can behave weirdly or collide with built-ins:

const cart = {};
cart["toString"] = { id: 1, name: "weird key" };

console.log(cart.toString); // not always what you expect
Enter fullscreen mode Exit fullscreen mode

If you really want an object as a dictionary, a safer option is:

const cart = Object.create(null); // no prototype
cart["toString"] = { id: 1, name: "safe now" };
console.log(cart["toString"]); // works as a normal key
Enter fullscreen mode Exit fullscreen mode

Iteration patterns

With objects you typically use Object.keys() / Object.entries() (not for...of directly):

const cart = {
  "id-1": { id: 1, name: "first", price: 10 },
  "id-2": { id: 2, name: "second", price: 20 },
};

for (const [key, value] of Object.entries(cart)) {
  console.log(key, value.name);
}
Enter fullscreen mode Exit fullscreen mode

So objects can work, but you need to be mindful of prototype quirks + how you iterate. Maps avoid both problems and give you a cleaner API for “data keyed by id”.

Collapse
 
edriso profile image
Mohamed Idris

Quick summary for anyone skimming:

  • Array works, but updating/looking up by id usually means doing .find() / .filter() every time (fine for small carts, gets annoying as it grows).
  • Object gives fast lookup by key, but keys are basically strings only, and you can run into some “object quirks” when iterating or dealing with inherited properties.
  • Map is a really nice fit for a cart because it’s built for key/value storage:

    • clean API: set / get / has / delete
    • easy iteration
    • keys can be any type (numbers are great for product IDs)
    • size is built-in

Small example (using numeric product IDs):

const cart = new Map();

cart.set(1, { id: 1, name: "Apple", price: 0.5, qty: 3 });
cart.set(2, { id: 2, name: "Banana", price: 0.3, qty: 6 });

console.log(cart.get(2)); // { id: 2, name: 'Banana', price: 0.3, qty: 6 }

cart.delete(1);

for (const [id, item] of cart) {
  console.log(id, item.name, item.qty);
}
Enter fullscreen mode Exit fullscreen mode

And if you already have an array, converting is super clean:

const items = [
  { id: 1, name: "first", price: 10 },
  { id: 2, name: "second", price: 20 },
];

const cart = new Map(items.map((item) => [item.id, item]));
console.log(Array.from(cart.entries()));
Enter fullscreen mode Exit fullscreen mode

Map is underrated for this kind of “lookup/update by id” data.

Collapse
 
edriso profile image
Mohamed Idris

Extra (Video)