Search code examples
javascriptfirst-class-functionsfunction-expression

Difficulty Iterating Through Function Call - First Class Functions


The code I have provided executes properly, however as you will see it offers refreshments to each guest repeatedly before moving on to the next guest.

I'm scratching my head as to how I can alter my code, in an efficient way, so that each customer is offered refreshments in turn, but still attended to four times each when the program is run.

All suggestions are greatly appreciated.

JS:

var guests = [
    {name: "Rick Sanchez", paid: false, loyaltyCard: true},
    {name: "Morty Smith", paid: true, loyaltyCard: true},
    {name: "Beth Smith", paid: true, loyaltyCard: false},
    {name: "Jerry Smith", paid: true, loyaltyCard: false},
    {name: "Sleepy Gary", paid: true, loyaltyCard: false},
    {name: "Summer Smith", paid: true, loyaltyCard: false},
    {name: "Mr. Poopybutthole", paid: true, loyaltyCard: true},
    {name: "Pencilvester", paid: true, loyaltyCard: false}
];


function serveGuest(guest) {
    var getRefreshmentOrder = createRefreshmentOrder(guest);
    
    getRefreshmentOrder();
    // Loyalty Stamps
    getRefreshmentOrder();
    getRefreshmentOrder();
    // Agressive Advertisment
    getRefreshmentOrder();
    // Thank you. Come again.
}

function createRefreshmentOrder(guest) {
    var orderFunction;

    if (guest.loyaltyCard) {
        orderFunction = function() {
            alert("Would you like any premium refreshments from our Membership Menu, at no extra cost?");
        };
    } else {
        orderFunction = function() {
            alert("Can we get you any refreshments?");
        };
    }
    return orderFunction;
}

function serveAllGuests(guests) {
    for (var i = 0; i < guests.length; i++) {
        serveGuest(guests[i]);
    }
}

serveAllGuests(guests);



Solution

  • This is probably how I would do it to clean things up and organize it a little better.

    Basically, this gives you two functions - takeOrder(guest) and takeOrders(guests), so you can either serve a single guest by just calling the former, or serve an array of guests using the latter. Either way, they both boil down to calling the takeOrder function on an instance of a guest, so you can just update that one function to do whatever it needs to do and you’re covered everywhere.

    It also allows you to change the number of times you’re going to serve them by updating the value in the totalNumberOfTimesToServe constant.

    const guests = [
      { name: "Rick Sanchez", paid: false, loyaltyCard: true },
      { name: "Morty Smith", paid: true, loyaltyCard: true },
      { name: "Beth Smith", paid: true, loyaltyCard: false },
      { name: "Jerry Smith", paid: true, loyaltyCard: false },
      { name: "Sleepy Gary", paid: true, loyaltyCard: false },
      { name: "Summer Smith", paid: true, loyaltyCard: false },
      { name: "Mr. Poopybutthole", paid: true, loyaltyCard: true },
      { name: "Pencilvester", paid: true, loyaltyCard: false }
    ];
    const totalNumberOfTimesToServe = 4;
    
    var timesServed = 0;
    
    function takeOrder(guest) {
      if (guest.loyaltyCard) {
        console.log(
          `Would you like any premium refreshments from our Membership Menu, at no extra cost, ${guest.name}?`
        );
      } else {
        console.log(`Can we get you any refreshments, ${guest.name}?`);
      }
    }
    
    function takeOrders(guests) {
      // take orders for each guest until we've fulfilled our iteration count
      while (timesServed < totalNumberOfTimesToServe) {
        console.log(`Serving number: ${timesServed + 1}`);
    
        guests.forEach((guest) => {
          takeOrder(guest);
        });
    
        // after each iteration of taking orders, increment our times served by one
        timesServed++;
      }
    
      // reset our times served back to 0
      timesServed = 0;
    }
    
    takeOrders(guests);

    You can see it running in this codepen, too: https://codepen.io/barneychampaign/pen/oNzNOXv