web-dev-qa-db-fra.com

Rejoignez un tableau par des virgules et "et"

Je veux convertir le tableau ['one', 'two', 'three', 'four'] en one, two, three and four

Notez que les premiers éléments ont une virgule, mais qu'il y a le mot and entre l'avant-dernier et le dernier.

La meilleure solution que j'ai trouvée:

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

Il est basé sur l'ajout de virgules à la fin - à l'exception de l'avant-dernier (a.length - 2) et avec un moyen d'éviter la dernière virgule (a.length - 2).

Sûrement, il doit y avoir une meilleure façon, plus nette et plus intelligente de faire cela?

C'est un sujet difficile à rechercher sur les moteurs de recherche car il contient les mots "et" ...

19
Merc

Une option serait de pop le dernier élément, puis join tout le reste par des virgules, et de concaténer avec and plus le dernier élément:

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

Si vous ne pouvez pas muter le tableau d'entrée, utilisez plutôt slice, et s'il ne peut y avoir qu'un seul élément dans le tableau d'entrée, vérifiez d'abord la longueur du tableau:

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
CertainPerformance

J'aime l'approche de Mark Meyer (et je voterais si j'avais le représentant) car elle ne modifie pas l'entrée. Voici mon tour:

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

Vous pouvez utiliser Array.prototype.slice () lorsque array.length est supérieur à 1 et exclut le reste des cas:

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

Exemple de code:

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

À partir de V8 v7.2 et Chrome 72, vous pouvez utiliser le doux Intl.ListFormat API. Il se chargera également de localiser votre liste sur demande, ce qui pourrait être très utile si vous en avez besoin.

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'

Vous pouvez même spécifier des options pour en faire une interruption et utiliser "ou" au lieu de "et", ou pour formater des unités telles que "3 ft, 7 in".

Références
API Intl.ListFormat - Développeurs Google
V8 version v7.2

8
Baptiste Candellier

Une autre approche pourrait être d'utiliser la méthode splice pour supprimer les deux derniers éléments du tableau et les joindre à l'aide du jeton and. Après cela, vous pouvez à nouveau pousser ce résultat sur le tableau et enfin joindre tous les éléments à l'aide du , séparateur.


Mis à jour en:

1) Montrez comment cela fonctionne pour plusieurs cas (aucun contrôle supplémentaire nécessaire sur la longueur du tableau).

2) Enveloppez la logique dans une méthode.

3) Ne modifiez pas le tableau d'origine (si cela n'est pas requis).

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

Utilisation de Array # Reduce:

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

2
xqc winston main

Intl.ListFormat est exactement ce que vous voulez. Bien que seuls Chrome 72 + et Opera 60 + soient pris en charge en mai, 2019, un polyfill est disponible pour les autres navigateurs: 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