Присоединяйтесь к массиву запятыми и "и" - PullRequest
0 голосов
/ 21 декабря 2018

Я хочу преобразовать массив ['one', 'two', 'three', 'four'] в one, two, three and four

Обратите внимание, что первые элементы имеют запятую, но между вторым последним и последним есть слово and.

Лучшее решение, которое я придумал:

a.reduce( (res, v, i) => i === a.length - 2 ? res + v + ' and ' : res + v + ( i == a.length -1? '' : ', '), '' )

Оно основано на добавлении запятых в end - за исключением второгопоследний (a.length - 2) и способ избежать последней запятой (a.length - 2).

ОБЯЗАТЕЛЬНО должен быть лучший, аккуратный, более разумный способ сделать это?

Это сложная тема для поиска в поисковых системах, потому что она содержит слово "и" ...

Ответы [ 7 ]

0 голосов
/ 21 декабря 2018

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

['one', 'two', 'three', 'four'].reduce( (a, b, i, array) => a + (i < array.length - 1 ? ', ' : ' and ') + b)

0 голосов
/ 12 мая 2019

Intl.ListFormat это именно то, что вы хотите.Хотя в мае 2019 года поддерживаются только Chrome 72 + и Opera 60 + , для других браузеров доступен полифилл: https://github.com/zbraniecki/IntlListFormat

const list = ['A', 'B', 'C', 'D'];

// With Oxford comma 
const lfOxfordComma = new Intl.ListFormat('en', {
  style: 'long',
  type: 'conjunction'
});
console.log(lfOxfordComma.format(list)); // → A, B, C, and D


// Without Oxford comma 
const lfComma = new Intl.ListFormat('en-GB', {
  style: 'long',
  type: 'conjunction'
});
console.log(lfComma.format(list)); // → A, B, C and D
0 голосов
/ 21 декабря 2018

Начиная с V8 v7.2 и Chrome 72, вы можете использовать приятный Intl.ListFormat API.Он также позаботится о локализации вашего списка по запросу, что может быть очень полезно, если вам это нужно.

const lf = new Intl.ListFormat('en');
lf.format(['Frank']);
// → 'Frank'
lf.format(['Frank', 'Christine']);
// → 'Frank and Christine'
lf.format(['Frank', 'Christine', 'Flora']);
// → 'Frank, Christine, and Flora'
lf.format(['Frank', 'Christine', 'Flora', 'Harrison']);
// → 'Frank, Christine, Flora, and Harrison'

Вы можете даже указать опции, чтобы сделать это нарушением, и использовать «или» вместо «и», или для форматирования единиц, таких как «3 фута, 7 дюймов».

Ссылки
API Intl.ListFormat - Google Developers
V8 выпуск v7.2

0 голосов
/ 21 декабря 2018

Мне нравится подход Марка Мейера (и я бы его поддержал, если бы у меня был представитель), так как он не меняет ввод.Вот мое вращение:

function makeCommaSeparatedString(arr, useOxfordComma) {
    const listStart = arr.slice(0, -1).join(', ');
    const listEnd = arr.slice(-1);
    const conjunction = arr.length <= 1 ? '' :
        useOxfordComma && arr.length > 2 ? ', and ' : ' and ';

    return [listStart, listEnd].join(conjunction);
}

console.log(makeCommaSeparatedString(['one', 'two', 'three', 'four']));
// one, two, three and four
console.log(makeCommaSeparatedString(['one', 'two', 'three', 'four'], true));
// one, two, three, and four
console.log(makeCommaSeparatedString(['one', 'two'], true));
// one and two
console.log(makeCommaSeparatedString(['one']));
// one
console.log(makeCommaSeparatedString([]));
// 
0 голосов
/ 21 декабря 2018

Другим подходом может быть использование метода splice для удаления двух последних элементов массива и объединения их с помощью токена and.После этого вы можете снова вставить этот результат в массив и, наконец, объединить все элементы, используя разделитель ,.


Обновлено до:

1) Показать, как это работает для нескольких случаев (дополнительный контроль над длиной массива не требуется).

2) Обернуть логику внутри метода.

3) Не изменять исходный массив (если не требуется).

let arrayToCustomStr = (arr, enableMutate) =>
{
    // Clone the received array (if required).
    let a = enableMutate ? arr : arr.slice(0);

    // Convert the array to custom string.
    let removed = a.splice(-2, 2);
    a.push(removed.join(" and "));
    return a.join(", ");
}

// First example, mutate of original array is disabled.
let input1 = ['one', 'two', 'three', 'four'];
console.log("Result for input1:" , arrayToCustomStr(input1));
console.log("Original input1:", input1);

// Second example, mutate of original array is enabled.
let input2 = ['one', 'two'];
console.log("Result for input2:", arrayToCustomStr(input2, true));
console.log("Original input2:", input2);

// Third example, lenght of array is 1.
let input3 = ['one'];
console.log("Result for input3:", arrayToCustomStr(input3));

// Fourth example, empty array.
let input4 = [];
console.log("Result for input4:", arrayToCustomStr(input4));

// Plus example.
let bob = [
    "Don't worry about a thing",
    "Cause every little thing",
    "Gonna be all right",
    "Saying, don't worry about a thing..."
];
console.log("Result for bob:", arrayToCustomStr(bob));
.as-console-wrapper {
    top: 0px;
    max-height: 100% !important;
}
0 голосов
/ 21 декабря 2018

Вы можете использовать Array.prototype.slice () , когда array.length больше 1 и исключать остальные случаи:

const result = a => a.length > 1 
  ? `${a.slice(0, -1).join(', ')} and ${a.slice(-1)}` 
  : {0: '', 1: a[0]}[a.length];

Пример кода:

const input1 = ['one', 'two', 'three', 'four'];
const input2 = ['A Tale of Two Cities', 'Harry Potter and the smth', 'One Fish, Two Fish, Red Fish, Blue Fish'];
const input3 = ['one', 'two'];
const input4 = ['one'];
const input5 = [];

const result = a => a.length > 1 
  ? `${a.slice(0, -1).join(', ')} and ${a.slice(-1)}` 
  : {0: '', 1: a[0]}[a.length];

console.log(result(input1));
console.log(result(input2));
console.log(result(input3));
console.log(result(input4));
console.log(result(input5));
0 голосов
/ 21 декабря 2018

Один из вариантов: pop последний элемент, затем join все остальные через запятую и конкатенация с and плюс последний элемент:

const input = ['one', 'two', 'three', 'four'];
const last = input.pop();
const result = input.join(', ') + ' and ' + last;
console.log(result);

Если вы не можете изменить входной массив, используйте вместо него slice, и если во входном массиве может быть только один элемент, проверьте длину массивапервый:

function makeString(arr) {
  if (arr.length === 1) return arr[0];
  const firsts = arr.slice(0, arr.length - 1);
  const last = arr[arr.length - 1];
  return firsts.join(', ') + ' and ' + last;
}

console.log(makeString(['one', 'two', 'three', 'four']));
console.log(makeString(['one']));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...