Generieren einer einzelnen Zeichenfolge mit einem Oxford-Komma aus einer Liste

24

Was sind einige clevere (kurze und idiomatische) Ansätze, um eine Liste von Zeichenfolgen zu erstellen und eine einzelne ordnungsgemäß interpunktierte Zeichenfolge zurückzugeben, die aus der Liste erstellt wird, wobei jedes Element in Anführungszeichen gesetzt wird?

Dies kam für mich beim Experimentieren mit Groovy auf , wofür meine zu wörtliche, aber illustrative Lösung ist

def temp = things.collect({"\'${it}\'"})
switch (things.size()) {
    case 1:
        result = temp[0]
        break
    case 2:
        result = temp.join(" and ")
        break
    default:
        result = temp.take(temp.size()-1).join(", ") + ", and " + temp[-1]
        break
}

Das heißt, ['1']sollte nachgeben '1', ['1','2']sollte nachgeben '1 and 2', [sehen, was ich dort getan habe?] Und ['1','2','3']sollte nachgeben '1, 2, and 3'.

Ich habe einige gute Antworten für Groovy, aber ich würde gerne sehen, was andere Sprachen können.

Was sind einige kompakte clevere Ansätze in verschiedenen Sprachen, die die Merkmale und Redewendungen dieser Sprachen nutzen?

orome
quelle
6
Willkommen bei PPCG. Generell sind die hier gestellten Fragen eine Herausforderung für die Community. Als solche brauchen sie ein objektives Gewinnkriterium. Ich halte diese Frage für eine Code-Golf- Herausforderung. Können Sie es als solches kennzeichnen? Wenn ja, sollten Sie die Eingabe- und Ausgabespezifikationen ein wenig verschärfen.
Digital Trauma
7
Dies wäre mit echten Sätzen interessanter :['we invited the stripper','JFK','Stalin']
ThisSuitIsBlackNot
1
Können wir davon ausgehen, dass die Zeichenketten selbst noch keine Kommas enthalten?
Martin Ender
2
Die Herausforderung sollte den Titel "Wer gibt ein ---- über ein Oxford-Komma ?" Haben.
Igby Largeman
3
@OldCurmudgeon Ich denke, Sie meinen "amerikanisierten Müll";)
ThisSuitIsBlackNot

Antworten:

76

CSS, 132 116 115 Bytes

a:not(:last-child):nth-child(n+2):after,a:nth-last-child(n+3):after{content:","}a+:last-child:before{content:"and "

CSS kommt im Code-Golf nicht allzu oft vor, weil es nur Text formatieren kann, aber es funktioniert tatsächlich für diese Herausforderung, und ich dachte, es würde Spaß machen, es zu tun. Sehen Sie es in Aktion mit dem obigen Snippet (klicken Sie auf "Code-Snippet anzeigen").

Die Liste sollte sich in einer verknüpften HTML-Datei befinden, wobei jedes Element von <a>Tags umgeben und durch Zeilenumbrüche getrennt ist. Die Listenelemente sollten die einzigen Elemente in ihrem übergeordneten Element sein, z

<a>one</a>
<a>two</a>
<a>three</a>

Erläuterung

a:not(:last-child):nth-child(n+2)::after,
a:nth-last-child(n+3)::after {
    content: ",";
}

a + :last-child::before {
    content: "and ";
}

Betrachten wir die ungolfed Version oben. Wenn Sie mit der Funktionsweise von CSS nicht vertraut sind, ist alles außerhalb der geschweiften Klammern ein Selektor, der die Menge der HTML-Elemente bestimmt, für die die Deklarationen in den Klammern gelten. Jedes Selektor-Deklarations-Paar wird als Regel bezeichnet . (Es ist komplizierter, reicht aber für diese Erklärung aus.) Bevor ein Stil angewendet wird, wird die Liste nur durch Leerzeichen getrennt angezeigt.

Wir möchten nach jedem Wort Kommas einfügen, mit Ausnahme der letzten, mit Ausnahme von Listen mit zwei Wörtern, die keine Kommas enthalten. Der erste Selektor a:not(:last-child):nth-child(n+2):afterwählt alle Elemente mit Ausnahme des ersten und des letzten aus. :nth-child(n+2)ist eine kürzere Art zu sagen :not(:first-child), und es funktioniert im Grunde durch die Elemente , deren Index (beginnend bei 1) größer als oder gleich 2 Auswahl (Ja, es immer noch verwirrt mich ein wenig. Die MDN docs könnte helfen.)

Jetzt müssen wir nur das erste Element auswählen, um ein Komma zu erhalten, wenn es insgesamt drei oder mehr Elemente gibt. a:nth-last-child(n+3):afterFunktioniert wie :nth-child, zählt jedoch von hinten und wählt alle Elemente mit Ausnahme der letzten beiden aus. Das Komma nimmt die Vereinigung der beiden Mengen und wir verwenden das :after Pseudoelement , um contentunmittelbar nach jedem ausgewählten Element einzufügen.

Die zweite Regel ist einfacher. Wir müssen "und" vor dem letzten Element in der Liste einfügen, es sei denn, es ist ein einzelnes Element. Mit anderen Worten, wir müssen das letzte Element auswählen, dem ein anderes Element vorangeht. +ist der benachbarte Geschwister-Selektor in CSS.

NinjaBearMonkey
quelle
1
Brillant! Ich liebe es. : D
COTO
Wenn du nur verwenden würdest <li>.
Slebetman
1
<li>wäre ideal, aber das würde den Selektoren zwei zusätzliche Zeichen hinzufügen. Ich habe gewählt, <a>weil es ein Buchstabe ist und keine eigene Formatierung verwendet.
NinjaBearMonkey
Wow ... das ist sehr beeindruckend. Cleverness Award.
CSS als Top-Antwort? Nett.
Brandon
13

Haskell: 81, 77, 74 Zeichen

f[x]=x
f[x,y]=x++" and "++y
f[x,y,z]=x++", "++f[y++",",z]
f(x:y)=x++", "++f y

Haskell-Funktionen: Mustererkennung

user3389669
quelle
Sie können einige Leerzeichen entfernen
Ray
1
Sie könnten einfach entfernenf[x,y,z]
siehequ
Und jetzt ist es so ziemlich Standardrekursion. :)
siehequ
Sie haben das Oxford-Komma und Leerzeichen nach dem Komma vergessen - f["a","b","c"]soll es sein, "a, b, and c"aber es ist"a,b and c"
stolzer Haskeller
4
wie wäre es mit Golfen durch Ersetzen y++", and "++zdurch f[y++",",z]:)
stolzer Haskeller
7

Ruby, 47 Bytes

q=" and ";p$*[2]?(a=$*.pop;$**", "+?,+q+a):$**q

Erläuterung

  • Die Eingabe sind die Befehlszeilenargumente ( $*).
  • Wenn $*ein drittes Element vorhanden ist ( $*[2]nicht nil zurückgibt), nehmen Sie alle Elemente mit Ausnahme des letzten und wandeln Sie sie mit in einen durch Kommas getrennten String um Array#*. Fügen Sie schließlich ein zusätzliches Komma, die Zeichenfolge " and "und das letzte Befehlszeilenargument hinzu.
  • Wenn $*es kein drittes Element gibt, wurden zwei, eins oder null Argumente angegeben. Die Argumente können sicher mit der Zeichenfolge verbunden werden " and "und führen zu dem richtigen Ergebnis.
britishtea
quelle
6

Python 2 (61)

s=input()
d=s.pop()
print", ".join(s)+", and "[8-7*len(s):]+d

Der Haupttrick besteht darin, einen Teil des endgültigen Verbinders ", and "für ein und zwei Elemente abzuschneiden . Zum einen wird alles ausgeschnitten und zum anderen das Komma entfernt. Dies geschieht durch Ausschneiden [8-7*len(s):](wobei das seine nach dem anderen kürzer ist pop).

dKann leider nicht einfach durch seinen Ausdruck ersetzt werden, popsonst würde das zu spät passieren.

xnor
quelle
Sie könnten die erste sdurch ersetzen s=input()und die erste Zeile entfernen, wenn ich mich nicht irre. Spart 2 Zeichen.
Tomsmeding
@tomsmeding Ich verstehe nicht, was Sie vorschlagen. Der Code bezieht sich auf smehrere Male.
Xnor
Warten Sie, ich mache heute Morgen komische Sachen. Vergess das. :)
Tomsmeding
6

CSS, 62 Zeichen 112 Zeichen

Inspiriert von den anderen Einträgen, noch kürzer. Beachten Sie, dass A-Elemente nicht durch Leerzeichen getrennt sein dürfen:

a+a:before{content:", "}a+a:last-child:before{content:", and "

http://jsfiddle.net/olvlvl/1Ls79ocb/

Fix für die "Eins und Zwei", wie von Dennis angedeutet:

a+a:before{content:", "}a+a:last-child:before{content:", and "}a:first-child+a:last-child:before{content:" and "

http://jsfiddle.net/olvlvl/1Ls79ocb/3/

olvlvl
quelle
5

Perl (v 5.10+) - 37 35 34 28

@F>2&&s/ /, /g;s/.* \K/and /

zu verwenden perl -ape, mit der Liste versehener Raum getrennt an STDIN.

Ausgang für verschiedene Eingänge:

$ perl -ape '@F>2&&s/ /, /g;s/.* \K/and /'
oxford
oxford
oxford cambridge
oxford and cambridge
oxford cambridge comma
oxford, cambridge, and comma
oxford cambridge comma space
oxford, cambridge, comma, and space
abligh
quelle
Sie können dies um 3 Byte reduzieren, indem Sie Ihre letzte Ersetzung aufs/(\S+)$/and $1/
ThisSuitIsBlackNot
1
@ThisSuitIsBlackNot Sie können das '\ n' löschen (danke), aber Sie können die Leerzeichen nicht
löschen
Hoppla, hätte mit mehr Eingaben testen sollen. Wie auch immer, du hast den $Anker in deiner Bearbeitung vergessen , so dass eine Eingabe von foo bar bazwird foo, and bar, baz. Sie können auch eines der Leerzeichen entfernen , indem Sies/( \S+)$/ and$1/
ThisSuitIsBlackNot
Mein letzter Kommentar lässt Sie immer noch bei 35, aber Sie können schreiben, $#F>1wie Sie noch einen @F>2abschneiden. Entschuldigung für alle Vorschläge für Mikroverbesserungen, ich mag diese Antwort einfach wirklich :)
ThisSuitIsBlackNot
@ThisSuitIsBlackNicht überhaupt - Mikrobearbeitungen sind willkommen. Ich konkurriere heimlich mit 28 Bytes CJam und 30 Bytes Golfscript. Ich bin jedoch auf 34 gekommen, ohne die Übersetzung Ihres Kommentars zum letzten Mal zu machen (getestet mit echo -n ... | wc -c). Wenn Sie das Leerzeichen vorher verpassen (\S+), würden Sie auf 33 Zeichen kommen, aber wenn Sie eingeben, erhalten test thisSie test and this(zwei Leerzeichen danach test), also ohne mehr Ich denke, das ist falsch.
abligh
4

Javascript (63)

l=a.length;l>2&&(a[l-1]='and '+a[l-1]);a.join(l>2?', ':' and ')

Fälle:

  • a = [1] => 1
  • a = [1, 2] => 1 and 2
  • a = [1, 2, 3] => 1, 2, and 3

Vorsichtsmaßnahme: Hiermit wird das letzte Element in einem Array mit einer Länge> 2 geändert.

mway
quelle
2
&&
Chris Bloom
4

GNU sed - 69 Zeichen, davon 1 für -rflag

s/ /, /g
s/( [^ ]+)( [^ ]+)$/\1 and\2/
s/^([^,]+),([^,]+)$/\1 and\2/

Nimmt eine durch Leerzeichen getrennte Liste (ziemlich idiomatisch für Shell-Skripte).

Beispiel

$ sed -r -f oxfordcomma.sed <<< "1"
1
$ sed -r -f oxfordcomma.sed <<< "1 2"
1 and 2
$ sed -r -f oxfordcomma.sed <<< "1 2 3"
1, 2, and 3
$
Digitales Trauma
quelle
Ja, lass uns mit Code-Golf gehen .
Orome
Die zweite Ausgabe sollte 1 and 2statt1, 2
Optimizer
@Optimizer - ganz richtig. Fest.
Digital Trauma
3

Python 2 - 71, 70 68

s=input()
l=len(s)-1
print', '.join(s[:l])+', and '[l<2:]*(l>0)+s[l]

Anzahl der Zeichen einschließlich, inputund print.

Falko
quelle
3

Ruby, 57 Bytes

f=->l{s=l*', ';s.sub(/,(?!.*,)/,(l.size<3?'':?,)+' and')}

Ich verbinde die Zeichenfolge mit ,und ersetze dann das letzte Komma in der Zeichenfolge durch ein and(und optionales Komma, abhängig von der Listenlänge).

Martin Ender
quelle
3

Cobra - 60

do(l as String[])=l.join(', ',if(l.length<3,'',',')+' and ')

Mit der Cobra- List<of T>.joinFunktion können Sie für die letzten beiden Elemente der Liste ein anderes Trennzeichen festlegen, was diese Funktion so kurz macht.

Οurous
quelle
3

Perl - 59

sub f{$a=join', ',@_;$#_&&substr$a,(@_>2)-3,@_<3,' and';$a}

Verbindet die Liste mit Kommas. Wenn die Liste mehr als ein Element enthält, wird entweder ' and'nach dem letzten Komma hinzugefügt (wenn Länge> = 3) oder das letzte Komma durch dieses ersetzt (wenn Länge == 2).

faubi
quelle
3

PHP, 192 167 146 136 Zeichen:

$n=' and ';$s=count($a);echo ($s<3)?join($n,$a):join(', ',array_merge(array_slice($a,0,$s-2),Array(join(",$n",array_slice($a,-2,2)))));

Basierend auf einer Funktion, die ich vor Jahren auf http://www.christopherbloom.com/2011/05/21/join-implode-an-array-of-string-values-with-formatting/ geschrieben habe

Chris Bloom
quelle
Können Sie bitte Ihren Code (mit Oxford-Komma) in den Antworttext eingeben?
Ja Entschuldigung. Ich war auf meinem Handy und es würde den Code nicht richtig einfügen. Ich aktualisiere von meinem Desktop
Chris Bloom
@ Chrisbloom7 Auch wenn es trivial ist, etwas hinzuzufügen, sollte die Antwort einen funktionierenden Code enthalten, der nicht zu einem gemacht werden kann. Da das Ziel darin besteht, den Code so klein wie möglich zu halten, führt die Nicht-Veröffentlichung von Arbeitscode dazu, dass Ihre Punktzahl nicht vorhanden ist.
stolzer Haskeller
Entschuldigung nochmal. Erstmals Poster bei CG. Ich habe meine Antwort
Chris Bloom
3

Batch - 151 Bytes

@echo off&set f=for %%a in (%~1)do
%f% set/aa+=1
%f% set/ac+=1&if !c!==1 (set o=%%a)else if !c!==!a! (set o=!o!, and %%a)else set o=!o!, %%a
echo !o!

Hinweis; Sie müssen das Skript cmdmit dem /vSchalter aufrufen, der als festgelegt ist on, das ist, also muss ich nicht das langwierige setLocal enableDelayedExpansionin das Skript einschließen . Andernfalls addieren Sie 30 zur Byteanzahl und rufen Sie das Skript normal auf.

h:\uprof>cmd /von /c test.bat "1 2 3"
1, 2, and 3

h:\uprof>cmd /von /c test.bat "1 2 3 4 5"
1, 2, 3, 4, and 5
unclemeat
quelle
3

Groovy, 47 43 57 Zeichen, JavaScript ES6 56 Zeichen

Groovy:

(a[1]?a[0..-2].join(", ")+(a[2]?",":"")+" and ":"")+a[-1]

Da das Array mit Zeichen gefüllt ist, können wir ersetzen a.size>1 durcha[1]

JavaScript, ES6:

a.join(', ').replace(/,([^,]+)$/,`${a[2]?',':''} and$1`)

In beiden Fällen wird angenommen, dass die Variable a das betreffende Array hat.

Optimierer
quelle
6
Das Oxford-Komma ist das Komma vor der Konjunktion.
Dennis
3

PHP, 86 84 Zeichen

$a = ['one', 'two', 'three', 'four', 'five'];

Mit dem initialisierten Array beginnen wir zu zählen:

$L=count($a)-1;$S=', ';$L<2?($S=' and '):($a[$L]='and '.$a[$L]);echo implode($S,$a);

Schön gemacht:

$last_index = count($a) - 1;
$separator = ', ';
if ($last_index < 2) {
    $separator = ' and ';
} else {
    $a[$last_index] = 'and '.$a[$last_index];
}
echo implode($separator, $a);

Der letzte Eintrag in der Liste wird geändert. Dies sollte in Ordnung sein, da in PHP durch Arrayzuweisung und Funktionsaufrufe Kopien erstellt werden.

Damian Yerrick
quelle
3

CJam, 35 30 28 27 Bytes

q~)\_"and "L?@+a+_,2=", ">*

Dies ist ein Programm, das aus STDIN liest und in STDOUT druckt. Probieren Sie es online aus.

Wie es funktioniert

q~                                     " Q := eval(input())                               ";
  )                                    " P := Q.pop()                                     ";
   \_"and "L?@+                        " P := (Q ? 'and ' : '') + P                       ";
                a+                     " Q += [P]                                         ";
                  _,2=", ">            " J := ', '[(len(Q) == 2):]                        ";
                           *           " R := J.join(Q)                                   ";
                                       " print R (implicit)                               ";

Beispiellauf

$ cjam <(echo 'q~)\_"and "L?@+a+_,2=", ">*') <<< '["1"]'; echo
1
$ cjam <(echo 'q~)\_"and "L?@+a+_,2=", ">*') <<< '["1""2"]'; echo
1 and 2
$ cjam <(echo 'q~)\_"and "L?@+a+_,2=", ">*') <<< '["1""2""3"]'; echo
1, 2, and 3
$ cjam <(echo 'q~)\_"and "L?@+a+_,2=", ">*') <<< '["1""2""3""4"]'; echo
1, 2, 3, and 4
Dennis
quelle
Ich bin auf deinem Schwanz - siehe unten :-)
abligh
3

Google Sheets, 67 68 67 92 Bytes

=SUBSTITUTE(JOIN(", ",FILTER(A:A,A:A<>"")),",",IF(COUNTA(A:A)>2,",","")&" and",COUNTA(A:A)-1

Die Eingabe beginnt bei Zelle A1und wird fortgesetzt, solange noch viele Einträge vorhanden sind.
JOINFügt sie alle zu einer Zeichenfolge mit einem Komma dazwischen zusammen.
FILTEREntfernt alle Nicht-Leerzeichen, damit Sie am Ende keine unendlichen Kommas erhalten.
SUBSTITUTEersetzt das letzte Komma (gefunden vonCOUNTA Zählen der nicht leeren Eingaben).

Es ist nicht sehr aufregend, aber in einer einzelnen Zelle machbar.

Ingenieur Toast
quelle
Dies lässt das Oxford-Komma weg.
Umbrella
@Umbrella Nun, das war dumm von mir, nicht wahr? +1 Bytes
Ingenieur Toast
Sie sollten in der Lage sein, das Terminal )für -1 Byte aus dieser Formel zu entfernen. Naja, das war die schnellste Bearbeitung, die ich je gesehen habe +1
Taylor Scott
Zwei Notizen nach dem Testen dieses Befehls - A:A>""sollten konvertiert werden A:A<>""und dies führt nicht dazu, dass das Komma bei Fällen von nur 2 Objekten weggelassen wird
Taylor Scott
@TaylorScott Ich denke, ich habe immer nur mit Text getestet und das Problem mit verpasst >"". Die Quickie-Korrektur, die ich zuvor durchgeführt habe, wurde eindeutig nicht getestet. Ich weiß nicht , wie die Richtung , die gingen ...
Ingenieur Toast
2

JavaScript (ES6) 60

Es werden keine leeren Zeichenfolgen im Eingabearray angenommen

f=(a,b=a.pop())=>a[0]?a.join(', ')+(a[1]?',':'')+' and '+b:b

Test In FireFox / Firebug - Konsole

console.log(f(['We invited the stripper','JFK','Stalin']))

Ausgabe

 We invited the stripper, JFK, and Stalin
edc65
quelle
Wie führe ich das aus? Ich habe es node --harmonymit einer Reihe von Zeichenfolgen versucht var a = 'abcdefgh'.split('');, aber es sitzt dort nur mit einem ...und scheint nichts zu tun. Auch +1 für die Verwendung der einzigartigen ES6-Funktion ()=>.
Adrian
@Adrian Die Funktion gibt eine Zeichenfolge ohne Ausgabe zurück. Ich werde einen Test in der Antwort hinzufügen.
EDC65
Ich finde f=(a,b=a.pop())=>a[0]?a.join(', ')+', and '+b:bdas auch richtig und 13 Bytes kürzer.
Ingo Bürk
1
@ IngoBürk schneidet das Teil, das das Komma mit 2 Elementen behandelt. Erraten Sie, was? Bei 2 Items ist die Ausgabe falsch.
edc65
@ edc65 Ah, oh. Mai schlecht.
Ingo Bürk
2

JavaScript - 60 56 71 67 63

Nicht gerade ein idiomatischer Ansatz, aber ich hatte Spaß beim Schreiben und ich mag Regex.

Angenommen, das Array ist gespeichert in var a:

a.join((a.length>2?',':'')+' ').replace(/([^,\s])$/,"and $1")

Verkürzt durch einfaches Überprüfen des Index [2]: (yay boolean coercion)

a.join((!!a[2]?',':'')+' ').replace(/([^,\s])$/,'and $1')

Anscheinend nerve ich beim Testen und überspringe einen Single-Entry-Test. Hier ist die feste Version:

a.join((!!a[2]?',':'')+' ').replace(/([^,\s])$/,(!!a[1]?'and ':'')+'$1')

2 Zeichen durch Invertieren meiner Booleschen Werte und 3 weitere Zeichen durch Verschieben des Leerzeichens von der Verkettung in das then / else des ersten Ternärs:

a.join((!a[2]?' ':', ')).replace(/([^,\s])$/,(!a[1]?'':'and ')+'$1')

Vielen Dank an @tomsmeding, der mich daran erinnert hat, dass ich meine Booleschen nicht zwingen muss, weil JS das für mich tut. Ich bemerkte auch, dass ich vergessen hatte, die Klammern zu entfernen, die das erste Ternär von der Verkettung in der join()folgenden Zeile trennen :

a.join(a[2]?', ':' ').replace(/([^,\s])$/,(a[1]?'and ':'')+'$1')

Habe ich das richtig gemacht? Obligatorische neue Entschuldigung für Golfer.

Adrian
quelle
1
Regex zu mögen ist als Masochismus bekannt.
Siehe auch
Eigentlich hast du das gar nicht gebraucht !!; a[2]?A:Bfunktioniert schon. Möglicherweise müssen Sie Ihre Booleschen Werte erneut invertieren .
Tomsmeding
@tomsmeding - Sie haben Recht. Ich bin immer vorsichtig mit JavaScripts Standardverhalten bei booleschem Zwang, daher habe ich die Gewohnheit, meine booleschen Werte manuell zu erzwingen ...
Adrian
@Adrian Korrektur: für jeden Wert , sondern eine leere Zeichenfolge, a[i]um entspricht wahr . Naja fast. Ich gehe davon aus, dass Ihr Array bei zwei Eingängen die Länge zwei hat. Dann a[2]===undefinedund undefinedbewertet zu false. BEARBEITEN: Ihre Bearbeitung ist, was ich meinte :)
Tomsmeding
2

Golfscript - 31 39 34 30

Hallo Welt! Ich bin ein langjähriger Lauerer, das erste Mal Poster. Hier ist meine 30-Byte-Lösung in Golfscript (vorausgesetzt, das Array wie [1 2 3] ist bereits auf dem Stapel).

.,3<" and ":A{~A(;\+]", "}if*

Die Ergebnisse sind für alle Testfälle zutreffend.

EDIT: Nehmen Sie das, CJam!

Josiah Winslow
quelle
Bearbeitet, um das Array der Länge 1 zu berücksichtigen.
Josiah Winslow
Bearbeitet für einen effizienteren Algorithmus.
Josiah Winslow
Der Kampf geht weiter. : P
Dennis
Ah, aber jetzt sind wir gerade. : P
Josiah Winslow
2

Xojo, 52 71 83 Zeichen

dim i as int8=ubound(L)
L(i)=if(i=0,"","and ")+L(i)
Return L.Join(if(i=1," ",", ")

Beachten Sie, dass UBound um eins kürzer als die Array-Länge ist.

Silberkuchen
quelle
Dies scheint das Komma hinzuzufügen, wenn es 2 Elemente gibt - sollte nicht
edc65
Guter Fang. Zum Reparieren bearbeitet.
Silberkuchen
2

Excel VBA, 108 Bytes

Anonyme VBE-Direktfensterfunktion, die Eingaben als durch Leerzeichen begrenztes Array vom Bereich A1und von den Ausgaben zum VBE-Direktfenster übernimmt .

x=Split([A1]):y=UBound(x):For i=0To y-2:?x(i)", ";:Next:If y>0Then?x(i)IIf(y>1,",","")" and "x(i+1)Else?[A1]
Taylor Scott
quelle
1

Schläger 87

(define(f x)(string-join(map ~a x)", "#:before-last(if(= 2(length x))" and "", and ")))
Matthew Butterick
quelle
Ich finde die Funktionsnamen in Lisps immer noch viel zu lang zum Golfen.
Siehe auch
1

Python 62 Zeichen

Angenommen, ich bin die Liste der Zeichenfolgen:

(" and", ", and")[len(i) < 2].join(", ".join(i).rsplit(",",1))
tief
quelle
1

C # 102 Zeichen

var i=m.Count(),l=i;if(l>2)l--;var r=string.Join(", ",m.Take(l));if(l!=i)r+=" and "+m.Last();return r;
Stephan Schinkel
quelle
1

Julia (53)

print(join(ARGS,", ",(endof(ARGS)>2?",":"")" and "))

Nimmt Args von STDIN und gibt sie an STDOUT aus

Lösung mit Base.join (items, delim [, last])

Bearbeiten:

Testfälle

julia oxfordComma.jl 1

1

julia oxfordComma.jl 1 2

1 und 2

julia oxfordComma.jl 1 2 3

1, 2 und 3

Grausamkeit
quelle
1
Ich kenne Julia nicht, aber es sieht so aus, als würde das Oxford-Komma nicht generiert.
Flornquake
@flornquake wird aufgrund des optionalen "letzten" Arguments
Cruor,
2
Es sollte 1, 2, and 3nicht sein 1, 2 and 3.
Flornquake
1

Rant (108)

[$[l:@b]:[r:each][s:[cmp:[rc];2;[is:different;,]]\s][before:[last:[notfirst:and\s]]][sync:;ordered][arg:b]]

Ungolfed:

[$[l:@b]:
    [r:each]                            # Repeat for each item
    [s:[cmp:[rc];2;[is:different;,]]\s] # Separate by comma if n > 2
    [before:[last:[notfirst:and\s]]]    # Insert "and" before last item
    [sync:;ordered]                     # Force forward order
    [arg:b]                             # Read list
]

Verwendung:

[$l:{A|B|C|D|E}]

Probieren Sie es online aus

Berkin
quelle
1

Pyth, 28

j>", "qlQ2+_t_Q+?"and "tQkeQ

Beispiele:

$ pyth programs/oxford.pyth <<< "['1']"
1

$ pyth programs/oxford.pyth <<< "['1','2']"
1 and 2

$ pyth programs/oxford.pyth <<< "['1','2','3']"
1, 2, and 3
isaacg
quelle
Ich kann nicht scheinen, herauszufinden, wie die Eingabe formatiert werden sollte.
Dennis
@ Tennis Ich werde einige Testfälle hinzufügen.
isaacg
Ich hatte es tatsächlich versucht, aber es funktionierte nicht mit meiner Version von Pyth ( TypeError: can only concatenate list (not "str") to list). Es funktioniert gut mit der neuesten Version.
Dennis
@Dennis Ja, die Regel zum Hinzufügen zur Liste wurde erst kürzlich hinzugefügt.
Isaacg
1

PHP - 72

Richten Sie die Eingabe ein:

$i=[1,2,3,4,5];

Und dann der Prozess:

$x=count($i)-1;if($x) {$i[$x]=" and ".$i[$x];}echo join($x>1?",":"",$i);
Apathie-
quelle