Поверните массив в грамматически правильное предложение с запятой

Если у меня есть массив в Javascript, который выглядит как

searchComponents = ['element1', 'element2', 'element3'];

Какова необходимая логика, чтобы превратить это в предложение вроде:

"element1, element2 и element3"

Аналогично, если есть только два элемента, он должен выглядеть так:

"element1 и element2"

и так далее и тому подобное. Я застрял.

Ответ 1

Одно простое решение:

function arrayToSentence (arr) {
    var last = arr.pop();
    return arr.join(', ') + ' and ' + last;
}

console.log(arrayToSentence(['one','two','three']));

JS Fiddle demo.

И немного более сложное/смешное решение (потому что кому не нравится глупо, иногда...):

function arrayToSentence (arr) {
    var len = arr.length;
    return arr.reduce(function(a,b,c){
        return a + (c - 1 === length ? ', ' : ' and ') + b;
    });
}

console.log(arrayToSentence(['one','two','three']));

JS Fiddle demo.

Литература:

Ответ 2

function toSentence(arr) {
  return arr.slice(0, -2).join(', ') + 
    (arr.slice(0, -2).length ? ', ' : '') + 
    arr.slice(-2).join(' and ');
}

Использование

toSentence([1])

1

toSentence([1, 2])

1 и 2

toSentence([1, 2, 3])

1, 2 и 3

toSentence([1, 2, 3, 4, 5, 6])

1, 2, 3, 4, 5 и 6

Ответ 3

Попробуйте мою составную библиотеку:

https://github.com/adamshaylor/compound-subject

Он включает в себя средства контроля над тем, какой символ следует разграничить (например, запятыми или точкой с запятой), а также ограничить все предметы (т.е. "Оксфордская запятая" ).

Ответ 4

Более ES6/7 версия без мутации:

function buildSentence (arr = []) {
  if (arr.length === 0) {
    return '';
  }

  if (arr.length === 1) {
    return arr[0];
  }

  const newArr = [...arr];
  const last = newArr.pop();    
  return newArr.join(', ') + ' and ' + last;
}
buildSentence([]);
buildSentence(['a']);
buildSentence(['a', 'b']);
buildSentence(['a', 'b', 'c']);

Ответ 5

Вот один вкладыш:

const arrayToSentence = (a) => [a.slice(0, -1).join(', '), a.pop()].filter(w => w !== '').join(' and ');

console.log(arrayToSentence(['foo', 'bar', 'baz']));
console.log(arrayToSentence(['foo', 'bar']));
console.log(arrayToSentence(['foo']));
console.log(arrayToSentence([]));

Ответ 6

Как это...

function parseArray(arr) {
    var s=arr.toString();
    var c=s.lastIndexOf(",");
    if(c!=-1) s=(s.substr(0,c)+" and "+s.substr(c+1)).replace(/,/g,", ");
return s[0].toUpperCase()+s.substr(1)+".";
}

console.log(parseArray(["one", "two","three","four","five"]));
console.log(parseArray(["one", "two"]));
console.log(parseArray(["one"]));

Выход:

One, two, three, four and five.
One and two.
One.

Грамматически правильно?

Ответ 7

Вот типизированная версия, которая использует функции lodash:

import { concat, first, join, last, slice } from 'lodash'

function joinOxford (list: string[]): string {
  switch (list.length) {
  case 1: return first(list)
  case 1: return '${first(list)} and ${last(list)}'
  default: return join(concat(slice(list, 0, -1), ['and ${last(list)}']), ', ')
  }
}

Использование:

joinOxford([foo])
// => foo

joinOxford([foo, bar])
// => foo and bar

joinOxford([foo, bar, baz])
// => foo, bar, and baz

joinOxford([foo, bar, baz, qux, quux, quuz])
// => foo, bar, baz, qux, quux, and quuz

Ответ 8

Поздний ответ, но это моя попытка. Относительно простые, неизменные аргументы и работают для 0-N элементов.

const toListSentence = (arr) => arr.length < 3 ?
  arr.join(' and ') :
  '${arr.slice(0, -1).join(', ')}, and ${arr[arr.length - 1]}';

console.log(toListSentence([]));
console.log(toListSentence(['apple']));
console.log(toListSentence(['apple', 'banana']));
console.log(toListSentence(['apple', 'banana', 'peach']));