How does one join string-type array-items, each with a comma character, except for the last item which has to be joined by "and"?

without temporarily saved references but with mutation of the original strings array ...

const strings = ['white t-shirt', 'blue jeans', 'red hat', 'brown glasses'];

console.log(
  [strings.pop(), strings.join(', ')].reverse().join(' and ')
);
console.log('mutated ... strings :', strings);
.as-console-wrapper { min-height: 100%!important; top: 0; }

without temporarily saved references and this time without mutation of the original strings array ...

const strings = ['white t-shirt', 'blue jeans', 'red hat', 'brown glasses'];

console.log(
  [strings.slice(0, strings.length - 1).join(', '), ...strings.slice(-1)].join(' and ')
);
console.log('not mutated ... strings :', strings);
.as-console-wrapper { min-height: 100%!important; top: 0; }


There is a part of Intl API called Intl.ListFormat. If you want to have proper list formatting in accordance with locale rules I'd suggest you to use it instead of manual formatting.

For example there should be a comma before "and" in the provided case.

const strings = ['white t-shirt', 'blue jeans', 'red hat', 'brown glasses'];

const formatter = new Intl.ListFormat('en', { style: 'long', type: 'conjunction' });
console.log(formatter.format(strings));

const short = ['white t-shirt', 'blue jeans'];

console.log(formatter.format(short));


You can use an array's slice method to do it simply.

const arr = ['white t-shirt', 'blue jeans', 'red hat', 'brown glasses'];

const result = arr.slice(0, arr.length - 1).join(', ') + ' and ' + arr.slice(-1)[0];

console.log(result);