rjhilgefort
7/17/2017 - 10:10 PM

Coding Test: Personalize Coupons

Coding Test: Personalize Coupons

// isCouponInCategories :: Array<Object> => Object -> Boolean
const isCouponInCategories = categories => coupon =>
  categories.includes(coupon.category);

// percentDiscount :: Object -> Number
const percentDiscount = coupon => 
  ((coupon.couponAmount / coupon.itemPrice) * 100);

// TODO: I decided to remove the code after the list was reduced 
//       to the 10 coupons because of the "So in short" summary of 
//       the task. It seemed that composability was preferred over 
//       performance because of the ordering of the bullets. 
//       If performance were preferred over composability,
//       we would change the `filter` to a `reduce` and remove
//       the `code` during that pass over the data.
// personalizeCoupons :: (Array<Object>, Array<Object>) -> Array<Object>
const personalizeCoupons = (coupons, preferredCategories) =>
  coupons
    .filter(isCouponInCategories(preferredCategories))
    .sort((a, b) => {
      const aDiscount = percentDiscount(a);
      const bDiscount = percentDiscount(b);
      if (bDiscount < aDiscount) return -1;
      if (bDiscount > aDiscount) return 1;
      return 0;
    })
    .slice(0, 10)
    .map((coupon) => {
      delete coupon.code;
      return coupon;
    });