Filter an Array of Objects in JavaScript

Cover Image for Filter an Array of Objects in JavaScript

Using JavaScript array's built-in .filter() function allows us to create a new, "filtered" array. The new array's contents are limited to elements within the original array that pass the .filter() method's test, which is contained within a callback function.

Check out this basic filtering example to visualize the fundamentals:

// Original array containing the numbers 1-5
const numbers = [1, 2, 3, 4, 5];

// Use the built-in `.filter(callback)` method to only include numbers
// that are greater than `3`. Said another way, this filter method's 
// callback excludes numbers that are less than or equal to `3`
const numbersGreaterThanThree = numbers.filter((value) => {
  return value > 3;
});

console.log('numbersGreaterThanThree: ', numbersGreaterThanThree);
// numbersGreaterThanThree:  (2) [4, 5]

How to filter an array of objects in JavaScript

Let's filter an array of objects by building upon the above simplistic example. To filter an array of objects:

  1. Use the array's built-in .filter() method to iterate over each item in the original array
  2. If the item passes the filter's test, it will be included in the new array

Check out this example:

const shoppingCart = [
  { isOnSale: false, itemName: 'banana 🍌' },
  { isOnSale: true,  itemName: 'pepperoni pizza 🍕' },
  { isOnSale: false, itemName: 'donut 🍩' },
  { isOnSale: false, itemName: 'avocado 🥑' },
];

// Filter our array of shopping cart objects based on each item's
// boolean `isOnSale` property
const saleItems = shoppingCart.filter((item) => {
  return item.isOnSale;
});

console.log(saleItems);

// Only one item in our cart is on sale:
//
// [
//   {
//     "isOnSale": true,
//     "itemName": "pepperoni pizza 🍕"
//   }
// ]

How to filter an array of objects on multiple properties

The above example is a bit contrived - often times our real world data won't be as simple to filter. Our applications' business requirements often make actual filter logic much more complicated.

Let's build on the above example to introduce more complex filtering logic - let's filter our array of shopping cart objects based on whether their eligible for a customer's coupon.

// Create a new shopping cart
// Here we've added a `quantity` value and `coupon`
const shoppingCart = [
  { 
    quantity: 1,
    itemName: 'pepperoni pizza 🍕', 
    itemPrice: 7.99,
    coupon: {
      couponName: 'buy-two-get-one-free',
      minimumQuantity: 2
    },
  },
  { 
    quantity: 3,
    itemName: 'donut 🍩', 
    itemPrice: .99,
    coupon: {
      couponName: 'buy-two-get-one-free',
      minimumQuantity: 2,
    }
  },
];

const customerCoupon = 'buy-two-get-one-free';

const itemsEligibleForCoupon = shoppingCart.filter((item) => {
  // Check that the customer's coupon matches the item's eligible coupon
  const hasCoupon = item.coupon.couponName === customerCoupon;

  // Check that the customer has the minimum quantity required to be
  // eligible for the coupon in their cart
  const hasQuantity = item.quantity >= item.coupon.minimumQuantity;
  
  // Return true if the customer has the coupon AND the customer has
  // the minimum required quantity
  return hasCoupon && hasQuantity;
});

console.log(itemsEligibleForCoupon);

// We only output the "donut" because the customer does not have the 
// minimum require quantity for the "pepperoni pizza"'s coupon
[
  {
    "quantity": 3,
    "itemName": "donut 🍩",
    "itemPrice": 0.99,
    "coupon": {
        "couponName": "buy-two-get-one-free",
        "minimumQuantity": 2
    }
  }
]

Use .reduce() to filter an array of objects

Receipts often include the customer's savings when purchasing items that are on sale.

For a more advanced example, let's use .reduce() to (1st) filter our array of objects and (2nd) calculate the customer's total sale savings.

Imagine the following customer's cart:

const shoppingCart = [
  { 
    quantity: 1,
    itemName: 'pepperoni pizza 🍕', 
    itemPrice: 7.99,
    salePrice: 5.99,
    isOnSale: true,
  },
  { 
    quantity: 1,
    itemName: 'donut 🍩', 
    itemPrice: .99,
    salePrice: .89,
    isOnSale: false,
  },
];

In the above cart, the pepperoni pizza is on sale, but the donut is not.

Here's an example of how we can use .reduce() to both filter and compute the customer's total savings:

const shoppingCart = [
  { 
    quantity: 1,
    itemName: 'pepperoni pizza 🍕', 
    itemPrice: 7.99,
    salePrice: 5.99,
    isOnSale: true,
  },
  { 
    quantity: 1,
    itemName: 'donut 🍩', 
    itemPrice: .99,
    salePrice: .89,
    isOnSale: false,
  },
];

const totalSavings = shoppingCart.reduce((savings, item) => {
  // Only calculate the sale savings if the item is on sale
  if (item.isOnSale) {
    const saleDiscount = item.itemPrice - item.salePrice;
    const savingsForItem = saleDiscount * item.quantity;

    return savings + savingsForItem;
  }

  // If the item is not on sale, return the current savings value
  return savings;
}, 0); // Initialize the reduce function with 0

console.log('totalSavings: ', totalSavings);
// totalSavings:  2

We expect the totalSavings to be 2 because:

  • The customer purchased 1x 'pepperoni pizza 🍕' that is on sale
  • The pizza's standard price is 7.99, but is on sale for 5.99
  • 7.99 - 5.99 = 2
  • The 'donut 🍩' is not on sale, so it isn't included in the total savings calculation

Wrapping up

Real world shopping cart logic is often significantly more complicated than the above examples. But, they're still helpful starting points when understanding how array of objects can be filtered.

Keep in mind that the above example using .reduce() isn't the most straight foward way to filter an array of objects. However, it is a useful tool if you need to perform additional calculations on the objects' properties.