web-dev-qa-db-ja.com

コンマと「and」で配列を結合します

配列を変換したい['one', 'two', 'three', 'four'] into one, two, three and four

最初のアイテムにはカンマがありますが、最後から2番目のアイテムの間にWord andがあることに注意してください。

私が思いついた最高のソリューション:

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

end-にコンマを追加することに基づいています。ただし、最後から2番目のコンマ(a.length - 2)最後のコンマ(a.length - 2)。

確かにこれを行うためのより良い、よりきちんとした、よりインテリジェントな方法がなければなりませんか?

「and」という単語が含まれているため、検索エンジンで検索するのは難しいトピックです...

19
Merc

1つのオプションは、pop最後の項目、次にjoinすべてをカンマで区切り、andと最後の項目を連結することです。

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

入力配列を変更できない場合は、代わりにsliceを使用し、入力配列にアイテムが1つしかない場合は、最初に配列の長さを確認します。

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']));
24

入力を変更しないため、Mark Meyerのアプローチが気に入っています(担当者がいれば賛成票を投じます)。これが私のスピンです。

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([]));
// 
12
Jug

次を使用できます Array.prototype.slice() when 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));
8
Yosvel Quintero

V8 v7.2以降では、Chrome 72、甘いIntl.ListFormat AP​​I。また、要求時にリストのローカライズも行います。これは、必要な場合に非常に役立つ場合があります。

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'

中断するオプションを指定して、「and」の代わりに「or」を使用したり、「3 ft、7 in」などの単位をフォーマットしたりすることもできます。

参考文献
Intl.ListFormat API-Google Developers
V8リリースv7.2

8

別のアプローチとして、 splice メソッドを使用して配列の最後の2つの要素を削除し、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;
}
3
Shidersz

Array#reduceの使用:

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

2

Intl.ListFormat はまさにあなたが望むものです。 5月では、Chrome 72 +Opera 60 +のみがサポートされますが、 2019では、他のブラウザでポリフィルを使用できます: 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
1
zeaccs