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?
['we invited the stripper','JFK','Stalin']
Antworten:
CSS,
132116115 BytesCode-Snippet anzeigen
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, zErläuterung
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):after
wä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):after
Funktioniert 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 , umcontent
unmittelbar 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.quelle
<li>
.<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.Haskell:
81, 77,74 ZeichenHaskell-Funktionen: Mustererkennung
quelle
f[x,y,z]
f["a","b","c"]
soll es sein,"a, b, and c"
aber es ist"a,b and c"
y++", and "++z
durchf[y++",",z]
:)Ruby, 47 Bytes
Erläuterung
$*
).$*
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 umArray#*
. Fügen Sie schließlich ein zusätzliches Komma, die Zeichenfolge" and "
und das letzte Befehlszeilenargument hinzu.$*
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.quelle
Python 2 (61)
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 dass
eine nach dem anderen kürzer istpop
).d
Kann leider nicht einfach durch seinen Ausdruck ersetzt werden,pop
sonst würde das zu spät passieren.quelle
s
durch ersetzens=input()
und die erste Zeile entfernen, wenn ich mich nicht irre. Spart 2 Zeichen.s
mehrere Male.CSS,
62 Zeichen112 ZeichenInspiriert von den anderen Einträgen, noch kürzer. Beachten Sie, dass A-Elemente nicht durch Leerzeichen getrennt sein dürfen:
http://jsfiddle.net/olvlvl/1Ls79ocb/
Fix für die "Eins und Zwei", wie von Dennis angedeutet:
http://jsfiddle.net/olvlvl/1Ls79ocb/3/
quelle
Perl (v 5.10+) -
37353428zu verwenden
perl -ape
, mit der Liste versehener Raum getrennt anSTDIN
.Ausgang für verschiedene Eingänge:
quelle
s/(\S+)$/and $1/
$
Anker in deiner Bearbeitung vergessen , so dass eine Eingabe vonfoo bar baz
wirdfoo, and bar, baz
. Sie können auch eines der Leerzeichen entfernen , indem Sies/( \S+)$/ and$1/
$#F>1
wie Sie noch einen@F>2
abschneiden. Entschuldigung für alle Vorschläge für Mikroverbesserungen, ich mag diese Antwort einfach wirklich :)echo -n ... | wc -c)
. Wenn Sie das Leerzeichen vorher verpassen(\S+)
, würden Sie auf 33 Zeichen kommen, aber wenn Sie eingeben, erhaltentest this
Sietest and this
(zwei Leerzeichen danachtest
), also ohne mehr Ich denke, das ist falsch.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.
quelle
&&
GNU sed - 69 Zeichen, davon 1 für
-r
flagNimmt eine durch Leerzeichen getrennte Liste (ziemlich idiomatisch für Shell-Skripte).
Beispiel
quelle
1 and 2
statt1, 2
Python 2 -
71, 7068Anzahl der Zeichen einschließlich,
input
undprint
.quelle
Ruby, 57 Bytes
Ich verbinde die Zeichenfolge mit
,
und ersetze dann das letzte Komma in der Zeichenfolge durch einand
(und optionales Komma, abhängig von der Listenlänge).quelle
Cobra - 60
Mit der Cobra-
List<of T>.join
Funktion können Sie für die letzten beiden Elemente der Liste ein anderes Trennzeichen festlegen, was diese Funktion so kurz macht.quelle
Perl - 59
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).quelle
PHP,
192167146136 Zeichen: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
quelle
Batch - 151 Bytes
Hinweis; Sie müssen das Skript
cmd
mit dem/v
Schalter aufrufen, der als festgelegt iston
, das ist, also muss ich nicht das langwierigesetLocal enableDelayedExpansion
in das Skript einschließen . Andernfalls addieren Sie 30 zur Byteanzahl und rufen Sie das Skript normal auf.quelle
Groovy,
47 4357 Zeichen, JavaScript ES6 56 ZeichenGroovy:
Da das Array mit Zeichen gefüllt ist, können wir ersetzen
a.size>1
durcha[1]
JavaScript, ES6:
In beiden Fällen wird angenommen, dass die Variable a das betreffende Array hat.
quelle
PHP,
8684 ZeichenMit dem initialisierten Array beginnen wir zu zählen:
Schön gemacht:
Der letzte Eintrag in der Liste wird geändert. Dies sollte in Ordnung sein, da in PHP durch Arrayzuweisung und Funktionsaufrufe Kopien erstellt werden.
quelle
CJam,
35302827 BytesDies ist ein Programm, das aus STDIN liest und in STDOUT druckt. Probieren Sie es online aus.
Wie es funktioniert
Beispiellauf
quelle
Google Sheets,
67686792 BytesDie Eingabe beginnt bei Zelle
A1
und wird fortgesetzt, solange noch viele Einträge vorhanden sind.JOIN
Fügt sie alle zu einer Zeichenfolge mit einem Komma dazwischen zusammen.FILTER
Entfernt alle Nicht-Leerzeichen, damit Sie am Ende keine unendlichen Kommas erhalten.SUBSTITUTE
ersetzt das letzte Komma (gefunden vonCOUNTA
Zählen der nicht leeren Eingaben).Es ist nicht sehr aufregend, aber in einer einzelnen Zelle machbar.
quelle
)
für -1 Byte aus dieser Formel zu entfernen. Naja, das war die schnellste Bearbeitung, die ich je gesehen habe +1A:A>""
sollten konvertiert werdenA:A<>""
und dies führt nicht dazu, dass das Komma bei Fällen von nur 2 Objekten weggelassen wird>""
. Die Quickie-Korrektur, die ich zuvor durchgeführt habe, wurde eindeutig nicht getestet. Ich weiß nicht , wie die Richtung , die gingen ...JavaScript (ES6) 60
Es werden keine leeren Zeichenfolgen im Eingabearray angenommen
Test In FireFox / Firebug - Konsole
Ausgabe
quelle
node --harmony
mit einer Reihe von Zeichenfolgen versuchtvar 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()=>
.f=(a,b=a.pop())=>a[0]?a.join(', ')+', and '+b:b
das auch richtig und 13 Bytes kürzer.JavaScript -
6056716763Nicht gerade ein idiomatischer Ansatz, aber ich hatte Spaß beim Schreiben und ich mag Regex.
Angenommen, das Array ist gespeichert in
var a
:Verkürzt durch einfaches Überprüfen des Index
[2]
: (yay boolean coercion)Anscheinend nerve ich beim Testen und überspringe einen Single-Entry-Test. Hier ist die feste Version:
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:
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 :Habe ich das richtig gemacht? Obligatorische neue Entschuldigung für Golfer.
quelle
!!
;a[2]?A:B
funktioniert schon. Möglicherweise müssen Sie Ihre Booleschen Werte erneut invertieren .a[i]
um entspricht wahr . Naja fast. Ich gehe davon aus, dass Ihr Array bei zwei Eingängen die Länge zwei hat. Danna[2]===undefined
undundefined
bewertet zufalse
. BEARBEITEN: Ihre Bearbeitung ist, was ich meinte :)Golfscript -
31393430Hallo 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).
Die Ergebnisse sind für alle Testfälle zutreffend.
EDIT: Nehmen Sie das, CJam!
quelle
Xojo,
527183 ZeichenBeachten Sie, dass UBound um eins kürzer als die Array-Länge ist.
quelle
Excel VBA, 108 Bytes
Anonyme VBE-Direktfensterfunktion, die Eingaben als durch Leerzeichen begrenztes Array vom Bereich
A1
und von den Ausgaben zum VBE-Direktfenster übernimmt .quelle
Schläger 87
quelle
Python 62 Zeichen
Angenommen, ich bin die Liste der Zeichenfolgen:
quelle
C # 102 Zeichen
quelle
Julia (53)
Nimmt Args von STDIN und gibt sie an STDOUT aus
Lösung mit Base.join (items, delim [, last])
Bearbeiten:
Testfälle
1
1 und 2
1, 2 und 3
quelle
1, 2, and 3
nicht sein1, 2 and 3
.Rant (108)
Ungolfed:
Verwendung:
Probieren Sie es online aus
quelle
Pyth, 28
Beispiele:
quelle
TypeError: can only concatenate list (not "str") to list
). Es funktioniert gut mit der neuesten Version.PHP - 72
Richten Sie die Eingabe ein:
Und dann der Prozess:
quelle