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" ...
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']));
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([]));
//
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));
À 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
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;
}
Utilisation de Array # Reduce:
['one', 'two', 'three', 'four'].reduce( (a, b, i, array) => a + (i < array.length - 1 ? ', ' : ' and ') + b)
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