CSS, 132 116 115 octets
a:not(:last-child):nth-child(n+2):after,a:nth-last-child(n+3):after{content:","}a+:last-child:before{content:"and "
<p>
<a>one</a>
</p>
<p>
<a>one</a>
<a>two</a>
</p>
<p>
<a>one</a>
<a>two</a>
<a>three</a>
</p>
<p>
<a>one</a>
<a>two</a>
<a>three</a>
<a>four</a>
</p>
a:not(:last-child):nth-child(n+2):after,a:nth-last-child(n+3):after{content:","}a+:last-child:before{content:"and "
CSS n'est pas vu trop souvent dans le golf de code car il ne peut que formater du texte, mais il fonctionne réellement pour ce défi et j'ai pensé que ce serait amusant à faire. Voyez-le en action en utilisant l'extrait de code ci-dessus (cliquez sur "Afficher l'extrait de code").
La liste doit être dans un fichier HTML lié avec chaque élément entouré de <a>
balises et séparé par des sauts de ligne. Les éléments de la liste doivent être les seuls éléments de leur élément parent, par exemple
<a>one</a>
<a>two</a>
<a>three</a>
Explication
a:not(:last-child):nth-child(n+2)::after,
a:nth-last-child(n+3)::after {
content: ",";
}
a + :last-child::before {
content: "and ";
}
Prenons la version non golfée ci-dessus. Si vous n'êtes pas familier avec le fonctionnement de CSS, tout ce qui se trouve en dehors des accolades est un sélecteur qui détermine l'ensemble des éléments HTML auxquels s'appliquent les déclarations à l'intérieur des accolades. Chaque paire sélecteur-déclaration est appelée une règle . (C'est plus compliqué que cela, mais suffira pour cette explication.) Avant d'appliquer un style, la liste apparaît séparée uniquement par des espaces.
Nous voulons ajouter des virgules après chaque mot, sauf le dernier, à l'exception des listes de deux mots, qui n'obtiennent aucune virgule. Le premier sélecteur,, a:not(:last-child):nth-child(n+2):after
sélectionne tous les éléments à l'exception du premier et du dernier. :nth-child(n+2)
est une façon plus courte de dire :not(:first-child)
, et cela fonctionne essentiellement en sélectionnant des éléments dont l'index (à partir de 1) est supérieur ou égal à 2. (Oui, cela m'embrouille encore un peu. Les documents MDN pourraient aider.)
Il nous suffit maintenant de sélectionner le premier élément pour obtenir une virgule s'il y a trois éléments ou plus au total. a:nth-last-child(n+3):after
fonctionne comme :nth-child
, mais en comptant de l'arrière, donc il sélectionne tous les éléments sauf les deux derniers. La virgule prend l'union des deux ensembles, et nous utilisons le :after
pseudo-élément pour ajouter content
immédiatement après chaque élément sélectionné.
La deuxième règle est plus simple. Nous devons ajouter "et" avant le dernier élément de la liste, sauf s'il s'agit d'un seul élément. En d'autres termes, nous devons sélectionner le dernier élément précédé d'un autre élément. +
est le sélecteur frère adjacent en CSS.