DEV Community

Discussion on: Daily Challenge #309 - Coffee Customization

Collapse
 
aminnairi profile image
Amin

JavaScript

const count = (count, item) => ({ ...count, [item]: (count[item] || 0) + 1 });
const announce = callback => (announcements, [item, count]) => [...announcements, callback(item, count)];
const pluralize = (count, text) => count > 1 ? `${text}s` : text;
const coffee = (kind, sugars = [], milks = []) => ({
  addSugar: sugar => coffee(kind, [...sugars, sugar]),
  addMilk: milk => coffee(kind, sugars, [...milks, milk]),
  announce: () => {
    const sugarCount = sugars.reduce(count, {});
    const sugarAnnouncement = Object.entries(sugarCount).reduce(announce((sugar, count) => `with ${count} ${sugar} ${pluralize(count, "sugar")}`), []);
    const milkCount = milks.reduce(count, {});
    const milkAnnouncement = Object.entries(milkCount).reduce(announce((fat, count) => `with ${count} ${fat}% fat ${pluralize(count, "milk")}`), []);
    const announcements = [...sugarAnnouncement, ...milkAnnouncement];
    return announcements.length > 0 ? `One ${kind} ${announcements.join(", ")}, please.` : `One ${kind}, please.`;
  }
});
Enter fullscreen mode Exit fullscreen mode

Usage

const firstOrder = 
  coffee("black coffee")
    .addSugar("regular")
    .addMilk(3.2)
    .announce();

const secondOrder = coffee("Cubano coffee").announce();

const thirdOrder = 
  coffee("Americano")
    .addSugar("brown")
    .addSugar("brown")
    .announce();

console.log(firstOrder);  // One black coffee with 1 regular sugar, with 1 3.2% fat milk, please.
console.log(secondOrder); // One Cubano coffee, please.
console.log(thirdOrder);  // One Americano with 2 brown sugars, please.
Enter fullscreen mode Exit fullscreen mode