4

I have an array of strings and I would like to display them as a comma separated string but add "and" for the last element. For example I have

var fruits = ["Banana", "Orange", "Apple", "Mango"];
var energy = fruits.join(' ,'); 

outputs

'Banana, Orange, Apple, Mango'

Is there any way the I add "and" for the last word so it outputs

'Banana, Orange, Apple and Mango'
1
  • You can use .reduce or replace the last comma in the string. Commented Oct 30, 2016 at 12:24

5 Answers 5

9

You may instead use Array.reduce function and implement your own logic, for example:

var fruits = ["Banana", "Orange", "Apple", "Mango"];
var energy = fruits.reduce(function (p, d, i) {
  return p + (i === fruits.length - 1 ? ' and ' : ', ') + d;
});
Sign up to request clarification or add additional context in comments.

4 Comments

This is a better example for a general solution.
this works but it is needed a condition for the first item in the array, otherwise a comman will be prepended ` var fruits = ["Banana", "Orange", "Apple", "Mango"]; var energy = fruits.reduce(function (p, d, i) { if(i === 0) { return d; } return p + (i === fruits.length - 1 ? ' and ' : ', ') + d; });`
Please elaborate what p, d and i mean in this context. Those are poor variable names and don't convey the necessary meaning.
@analytical_prat looking at the .reduce syntax: p = accumulator, d = currentValue, i = currentIndex
5

You can join the first 3 elements of the array using slice and join then append the last element concatenated with 'and'.

var fruits = ["Banana", "Orange", "Apple", "Mango"];
var energy = fruits.slice(0, fruits.length - 1).join(', '); 
energy += ' and ' + fruits[fruits.length - 1];

Comments

1

You can't pass a function to .join, unfortunately, so you do need to iterate through the loop and join it yourself:

const array = ['banana', 'apple', 'taco']

let result = array[0]
for (let i = 1; i < array.length; i++) {
  if (i < array.length - 1) {
    result += ', ' + array[i]
  } else {
    result += ' and ' + array[i]
  }
}

console.log(result)

You could make a function for this, though:

// General purpose custom/dynamic join function creator.
function dynamicJoin(fn) {
  return function(array) {
    let result = array[0]
    for (let i = 1; i < array.length; i++) {
      const joiner = fn(array[i - 1], array[i], i, array)
      result += joiner + array[i]
    }
    return result
  }
}

const joinCommaOrAnd = dynamicJoin(function(a, b, i, arr) {
  return (i === arr.length - 1) ? ' and ' : ', '
})

console.log(joinCommaOrAnd(['bread', 'fish', 'butter']))

Comments

1

Function toSentence of underscore.string has the exact functionality you want. If you don't want to get whole library, you could just borrow toSentence:

function toSentence(array, separator, lastSeparator, serial) {
  separator = separator || ', ';
  lastSeparator = lastSeparator || ' and ';
  var a = array.slice(),
    lastMember = a.pop();

  if (array.length > 2 && serial) lastSeparator = separator + lastSeparator;

  return a.length ? a.join(separator) + lastSeparator + lastMember : lastMember;
};

Comments

0

You can try this,

var delimiter = ', ';
var fruits = ["Banana", "Orange", "Apple", "Mango"];
var energy = fruits.join(delimiter); 
var index = energy.lastIndexOf(delimiter);
energy = energy.substring(0, index) + ' and ' + energy.substring(index + delimiter.length);

console.log(energy);

1 Comment

Thank you @Aruna that is exactly what I ended up doing and it did fit my requirements. I am sure the other suggestions are also correct but I have accepted this as the answer.

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.