Format a String of Names Exercise

Happy New Years! Hopefully I'll do a post on the last decade, but for now I want to at least try to do the #100daysofcode challenge. It's 11:30 pm now so I'm just squeaking by. Anyway, today's Kata was Format a string of names like 'Bart, Lisa & Maggie'. and comes to me courtesy of weavermedia. Time to dust the holiday cobwebs off!

Prompt: Format a String of Names

Given: an array containing hashes of names

Return: a string formatted as a list of names separated by commas except for the last two names, which should be separated by an ampersand.

Example:

list([ {name: 'Bart'}, {name: 'Lisa'}, {name: 'Maggie'} ])
// returns 'Bart, Lisa & Maggie'

list([ {name: 'Bart'}, {name: 'Lisa'} ])
// returns 'Bart & Lisa'

list([ {name: 'Bart'} ])
// returns 'Bart'

list([])
// returns ''

Solution: Format a string of names like 'Bart, Lisa & Maggie'

When we start out we're given something like this:

[{name: 'Bart'},{name: 'Lisa'},{name: 'Maggie'},{name: 'Homer'},{name: 'Marge'}]

So really all we need to do is map over the list, destructure the person object to pull out the name value, and push that into an array.

That looks like this:

const namesList = names.map(({ name }) => name);

At this point, namesList looks like ['Bart', 'Lisa', 'Maggie', 'Homer', 'Marge']. Joining the array with a .join(', ') gets us almost there, but now we're stuck with nothing but commas -- we really need to replace that last comma with an ampersand. Like with almost all of these Codewars Kata, I'm sure there's a fancy bit of RegEx that could do the heavy lifting for us on this, but I suck at RegEx. Instead I'm going to take the long route.

Step one: remove the last item of the array and store it in its own variable.

Step two: if there's any length to the namesList array now that its last item is gone, go ahead and join them into a string like mentioned above. Then we can concatenate the ampersand and the finalName variable using a template literal and return that entire string. If there's no length after popping the last name from the list, just return the finalName variable.

Lastly, we need to account for being passed an empty array. Simply wrap the whole bit of code in an if/else that will return an emptry string if we're given an empty array.

Here's what the whole solution looks like:

function list(names){
  if (names.length > 0) {
    const namesList = names.map(({ name }) => name);
    const finalName = namesList.pop();
    return namesList.length ? namesList.join(', ') + ` & ${finalName}` : finalName;
  } else {
    return '';
  }
};