88

I would like to use the reduce function instead of doing this:

var result = '';
authors.forEach(
    function(author) {
        result += author.name + ', ';
    }
);
console.log(result);

So in the array authors there are several names. Now I want to build a string with this names, separated by comma (except the last one).

var result = authors.reduce(function (author, index) {
    return author + ' ';
}, '');
console.log(result);
1
  • If you want to use reduce or a loop for some reason, you have to add a check to see if the current loop element is the last one or not. But just use join, it's one line of code to get what you want. Commented Jul 8, 2016 at 15:15

7 Answers 7

164

A flurry of answers just came in and here is one more!

The first option is using the native js join method which eliminates the need for reduce. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/join

var authors = ['some author', 'another author', 'last author'];
var authorString = authors.join(",");
console.log(authorString);

IMPORTANT - if you're array contains objects, then you might want to map it before joining:

var authors = [{name: 'some author'},{name: 'another author'},{name: 'last author'}]
var authorString = authors.map(function(author){
    return author.name;
}).join(",");
console.log(authorString);

or, if you're really fired up about using reduce, just make sure you use the previous value, current value and index when passing in the callback. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce

var authorString = authors.reduce(function(prevVal,currVal,idx){
    return idx == 0 ? currVal : prevVal + ', ' + currVal;
}, '')
console.log(authorString);

IMPORTANT - again if your array contains objects then you will want to make sure you are using the 'name property':

var authors = [{name: 'some author'},{name: 'another author'},{name: 'last author'}];
var authorString = authors.reduce(function(prevVal,currVal,idx){
    return idx == 0 ? currVal.name : prevVal + ', ' + currVal.name;
}, '')
console.log(authorString);
Sign up to request clarification or add additional context in comments.

2 Comments

for reduce is more beautiful solution var authors = [{ name: "a" }, { name: "b" }, { name: "c" }]; var res = authors.reduce((prev, curr) => (prev.name ? prev.name : prev) + ', ' + curr.name); console.log(res);
The two responses above DO NOT work if your array has only one element (in turn, it results in the whole object). Say, when your code reads variable data from DB; (prevVal, currVal, idx ) => idx == 0 ? currVal : prevVal + ', ' + currVal or ( prev, cur ) => (prev.name ? prev.name : prev ) + ', ' + curr.name ) will return { name:"a" }, whenever authors = [ {name:"a"} ] (one single item) Instead, to concatenate a field of JSON objects, simply use "map" like: authors.map( elem => elem.name ).join(", ") This will return expected result in all cases, including arrays of one element
23

Right, so it's an object. Let's map the names first then:

var result = authors.map(function( author ) {
    return author.name;
}).join(', ');

3 Comments

@SpencerJudd It's overcomplicated
I disagree. I think it's quite logical. You want to join the names. To get names, you use map. map is great at plucking properties from objects.
var names = authors.map(function(author) { return author.name; }); var result = names.join(', ');
10

You are reinventing join()

var authors = ["a","b","c"];
var str = authors.join(", ");
console.log(str);

if you want to use reduce add an if check

var authors = ["a","b","c"];

var result = authors.reduce(function (author, val, index) {
    var comma = author.length ? ", " : "";
    return author + comma + val;
}, '');
console.log(result);


Since I missed the mapping part to make people happy...

var authors = [{
  name: "a"
}, {
  name: "b"
}, {
  name: "c"
}];

var res = authors.map( function(val) { return val.name; }).join(", ");
console.log(res);

OR

var authors = [{
  name: "a"
}, {
  name: "b"
}, {
  name: "c"
}];
var result = authors.reduce(function(author, val, index) {
  var comma = author.length ? ", " : "";
  return author + comma + val.name;
}, '');
console.log(result);

6 Comments

He want to join the author names
@Bálint I did not get that from the post. An example would have helped.
Yeah, but the join one doesn't work, that's my problem
for reduce there is more beautiful solution var authors = [{ name: "a" }, { name: "b" }, { name: "c" }]; var res = authors.reduce((prev, curr) => (prev.name ? prev.name : prev) + ', ' + curr.name); console.log(res);
Even more beautiful version: authors.map(({ name }) => name).join(", "), alternatively: authors.map(({ name }) => name).reduce((a, b) => a === "" ? a : `${a}, ${b}`, "").
|
7

I came across this also. Most of these answers dont take into account that you want the authors name, meaning you have an array of objects.

A one line solution:

authors.reduce((prev, curr) => [...prev, curr.name], []).join(', ');

1 Comment

I know OP is asking for a reduce solution, but map is better suited for this. authors.map(({ name }) => name).join(", ")
1

Try this:

var authors = ["Mikel", "Brad", "Jessy", "Pof", "MArting"]
var result = authors.reduce( (prev, curr) => prev +', '+ curr )

console.log(result)

2 Comments

He wants to join the author names, not the authors. Each author is an object
if you refactor it a little it will work also for objects authors.reduce((prev, curr) => (prev.name ? prev.name : prev) + ', ' + curr.name);
1

I will add my 2 cents, two options here, either through map or using ternary operator:

const authors = [{name: 'John'}, {name: 'Jack'}, {name: 'Charles'}];

// Map
const reducedMap = authors.map(a => a.name).reduce((result, name) => `${result},${name}`);

// Ternary operator and initial value
const reducedTernary = authors.reduce((result, author) => `${result}${result ? ',' : ''}${author.name}` , '');

// Result :
// John,Jack,Charles

Comments

0

Here is a "Python Like" method to build a string in one line using an array or an Object.

// From an Array
['Hey', 'Hi', 'Hello!'].reduce((result, item, index) => (index !==0 ? `${result}, `: '')+`${item}`, '')


// From an Object
Object.entries({one: 1, two: 2, three: 3}).reduce((result, [key, value], index) => (index !==0 ? `${result}, `: '')+`${key} -> ${value}`, '')

I hope this helps. Cheers.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.