The why and the how
Several answers here rush to get the answer correct, but fail to build a robust, complete function. This answer is meant to be exhaustive and give you insight into why we would choose certain implementations over others
Contract
For your function to work on all [{name: String}] inputs (it should), you have to handle 3 cases
listofNames([]) // ''
listofNames([{name: 'Bart'}]) // 'Bart'
listofNames([{name: 'Bart'},{name: 'Lisa'}, ...]) // 'Bart, Lisa, ...'
- an empty array (
[]) returns an empty string
- a single name will just return that name –
', ' separator is not present
- an array of 2 or more names will return the names with separators between
Fulfilling your request
You asked to do this with Array.prototype.reduce, so we'll start there. What you'll notice about this answer is
- it works for all input scenarios described above, making
listOfNames a total function – several other answers fail to accommodate (1) and (2) above.
- it only uses a single
if, because that's all that is required – using if within the reducer is wasteful
*
const listOfNames = ([x,...xs]) => {
if (x === undefined)
return ''
else
return xs.reduce((acc, {name}) => acc + ', ' + name, x.name)
}
console.log(listOfNames([])) // ''
console.log(listOfNames([{name: 'Bart'}])) // 'Bart'
console.log(listOfNames([{name: 'Bart'}, {name: 'Lisa'}])) // 'Bart, Lisa'
A recommendation
You tagged this question with functional-programming so we're going to look at this from another perspective. What we did above was re-invent the Array.prototype.join function – only ours is actually a little worse.
console.log([].join(', ')) // ''
console.log(['Bart'].join(', ')) // 'Bart'
console.log(['Bart','Lisa'].join(', ')) // 'Bart, Lisa'
Our function is more specific and does not allow us to change the separator that is used (always uses ', ') and it assumes each element in the array has a name property.
In functional programming paradise kingdom, we should be making our functions as generic as possible - this allows for the most code recycling.
OK, so instead of reinventing a perfectly good function, we just need to convert our array of objects into an array of names, then use the perfectly good join function
const prop = x => y => y[x]
const listOfNames = xs =>
xs.map(prop('name')).join(', ')
console.log(listOfNames([])) // ''
console.log(listOfNames([{name: 'Bart'}])) // 'Bart'
console.log(listOfNames([{name: 'Bart'}, {name: 'Lisa'}])) // 'Bart, Lisa'
"But that's basically the same thing some other people said"
Yep, but clearly they don't realize why it's better. They think because the resulting code is shorter, it's somehow better - otherwise, they wouldn't have also given reduce solutions that are so horribly complex/incomplete.
Now you know why certain solutions are better than others, and you can evaluate which one is best for you
Quiz: can you name one reason why the map+join solution could be worse than our custom reduce solution?