Apa saja pendekatan yang pintar (singkat dan idiomatis) untuk mengambil daftar string dan mengembalikan satu string yang diberi tanda baca dengan benar yang dibangun dari daftar, dengan setiap elemen dikutip.
Ini muncul untuk saya saat bereksperimen dengan Groovy , yang mana solusi saya terlalu literal, tetapi ilustratif
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
}
Artinya, ['1']
harus menghasilkan '1'
, ['1','2']
harus menghasilkan '1 and 2'
, [lihat apa yang saya lakukan di sana?] Dan ['1','2','3']
harus menghasilkan '1, 2, and 3'
.
Saya punya beberapa jawaban bagus untuk Groovy, tetapi saya ingin melihat apa yang bisa dilakukan oleh bahasa lain.
Apa sajakah kompak pendekatan cerdas dalam berbagai bahasa yang mengambil keuntungan dari fitur dan idiom dari bahasa-bahasa tersebut?
['we invited the stripper','JFK','Stalin']
Jawaban:
CSS,
132116115 byteTampilkan cuplikan kode
CSS tidak terlihat terlalu sering dalam kode golf karena hanya dapat memformat teks, tetapi sebenarnya berfungsi untuk tantangan ini dan saya pikir itu akan menyenangkan untuk dilakukan. Lihat beraksi menggunakan cuplikan di atas (klik "Tampilkan cuplikan kode").
Daftar harus dalam file HTML tertaut dengan setiap elemen dikelilingi oleh
<a>
tag dan dipisahkan oleh jeda baris. Item daftar harus menjadi satu-satunya elemen dalam elemen induknya, misPenjelasan
Mari kita simak versi yang tidak diserang di atas. Jika Anda tidak terbiasa dengan cara kerja CSS, segala sesuatu di luar kurung kurawal adalah pemilih yang menentukan sekumpulan elemen HTML yang berlaku deklarasi di dalam kurung kurawal. Setiap pasangan pemilih-deklarasi disebut aturan . (Ini lebih rumit dari itu tetapi cukup untuk penjelasan ini.) Sebelum gaya apa pun diterapkan, daftar tampak dipisahkan oleh spasi saja.
Kami ingin menambahkan koma setelah setiap kata kecuali yang terakhir, kecuali untuk daftar dua kata, yang tidak mendapat koma. Pemilih pertama
a:not(:last-child):nth-child(n+2):after
,, memilih semua elemen kecuali yang pertama dan yang terakhir.:nth-child(n+2)
adalah cara yang lebih pendek untuk mengatakan:not(:first-child)
, dan pada dasarnya bekerja dengan memilih elemen yang indeksnya (mulai dari 1) lebih besar dari atau sama dengan 2. (Ya, itu masih sedikit membingungkan saya. Dokumen MDN mungkin membantu.)Sekarang kita hanya perlu memilih elemen pertama untuk mendapat koma jika ada tiga atau lebih elemen total.
a:nth-last-child(n+3):after
bekerja seperti:nth-child
, tetapi menghitung dari belakang, sehingga memilih semua elemen kecuali dua yang terakhir. Koma mengambil gabungan dari dua set, dan kami menggunakan:after
elemen pseudo untuk menambahkancontent
segera setelah setiap elemen yang dipilih.Aturan kedua lebih mudah. Kita perlu menambahkan "dan" sebelum elemen terakhir dalam daftar, kecuali itu adalah elemen tunggal. Dengan kata lain, kita perlu memilih elemen terakhir yang didahului oleh elemen lain.
+
adalah pemilih saudara yang berdekatan di CSS.sumber
<li>
.<li>
akan ideal, tetapi itu akan menambah dua karakter tambahan untuk pemilih. Saya memilih<a>
karena ini satu huruf dan tidak menerapkan pemformatannya sendiri.Haskell:
81, 7774 karakterFitur Haskell: Pencocokan pola
sumber
f[x,y,z]
f["a","b","c"]
seharusnya"a, b, and c"
tapi itu"a,b and c"
y++", and "++z
denganf[y++",",z]
:)Ruby, 47 byte
Penjelasan
$*
).$*
memiliki elemen ketiga ($*[2]
tidak mengembalikan nihil), ambil semua elemen minus yang terakhir dan ubah menjadi String yang dipisahkan dengan komaArray#*
. Terakhir, tambahkan koma tambahan, string," and "
dan argumen baris perintah terakhir.$*
tidak memiliki elemen ketiga, dua, satu, atau nol argumen diberikan. Argumen dapat dengan aman digabungkan dengan string" and "
dan menghasilkan hasil yang benar.sumber
Python 2 (61)
Trik utamanya adalah memotong bagian dari joiner terakhir
", and "
untuk satu dan dua elemen. Untuk satu, semuanya dipotong, dan untuk dua, koma dihilangkan. Ini dilakukan dengan mengiris[8-7*len(s):]
(mencatat bahwas
itu lebih pendek setelahpop
).Sayangnya,
d
tidak bisa hanya diganti dengan ekspresinya ataupop
akan terjadi terlambat.sumber
s
dengans=input()
dan menghapus baris pertama, jika saya tidak salah. Menghemat 2 karakter.s
beberapa kali.CSS,
62 karakter112 karakterTerinspirasi oleh entri lain, bahkan lebih pendek. Perhatikan bahwa ini mensyaratkan bahwa elemen A tidak dipisahkan oleh spasi putih:
http://jsfiddle.net/olvlvl/1Ls79ocb/
Perbaiki untuk "satu dan dua", seperti yang ditunjukkan oleh Dennis:
http://jsfiddle.net/olvlvl/1Ls79ocb/3/
sumber
Perl (v 5.10+) -
37353428untuk dijalankan
perl -ape
, dengan daftar ruang yang disediakan dihidupkanSTDIN
.Output untuk berbagai input:
sumber
s/(\S+)$/and $1/
$
jangkar di sunting, jadi inputfoo bar baz
menjadifoo, and bar, baz
. Selain itu, Anda dapat menghapus salah satu spasi dengan melakukans/( \S+)$/ and$1/
$#F>1
sebagai@F>2
untuk mencukur off satu lagi. Maaf untuk semua saran untuk perbaikan mikro, saya sangat suka jawaban ini :)echo -n ... | wc -c)
. Jika Anda kehilangan ruang sebelum(\S+)
Anda akan sampai 33 karakter, tetapi jika Anda memasukkantest this
Anda akan mendapatkantest and this
(dua spasi setelahtest
), jadi tanpa lebih Saya pikir itu salahJavascript (63)
l=a.length;l>2&&(a[l-1]='and '+a[l-1]);a.join(l>2?', ':' and ')
Kasus:
a = [1]
=>1
a = [1, 2]
=>1 and 2
a = [1, 2, 3]
=>1, 2, and 3
Peringatan: ini akan memodifikasi elemen terakhir dalam array dengan panjang> 2.
sumber
&&
GNU sed - 69 karakter termasuk 1 untuk
-r
benderaMengambil daftar yang dipisahkan oleh spasi (cukup idiomatis untuk skrip shell).
Contoh
sumber
1 and 2
bukan1, 2
Python 2 -
71, 7068Jumlah karakter termasuk keduanya,
input
danprint
.sumber
Ruby, 57 byte
Saya bergabung dengan string
,
dan kemudian saya mengganti koma terakhir dalam string denganand
(dan koma opsional tergantung pada panjang daftar).sumber
Cobra - 60
List<of T>.join
Fungsi Cobra memungkinkan Anda menentukan pemisah yang berbeda untuk dua elemen terakhir dari daftar, yang membuat ini sangat singkat.sumber
Perl - 59
Bergabung dengan daftar dengan koma, maka jika daftar memiliki lebih dari satu elemen, tambahkan
' and'
setelah koma terakhir (jika panjang> = 3), atau ganti koma terakhir dengan itu (jika panjang == 2).sumber
PHP,
192167146136 karakter:Berdasarkan suatu fungsi yang saya tulis bertahun-tahun yang lalu di http://www.christopherbloom.com/2011/05/21/join-implode-an-array-of-string-values-with-formatting/
sumber
Batch - 151 Bytes
Catatan; Anda harus memanggil skrip dari
cmd
dengan/v
sakelar yang diatur sebagaion
, ini jadi saya tidak harus menyertakansetLocal enableDelayedExpansion
skrip yang panjang . Jika tidak, tambahkan 30 ke jumlah byte, dan panggil script secara normal.sumber
Groovy,
47 4357 karakter, JavaScript ES6 56 karakterGroovy:
Karena array diisi dengan karakter, kita dapat menggantinya
a.size>1
dengana[1]
JavaScript, ES6:
Kedua kasus mengasumsikan bahwa variabel a memiliki array yang dimaksud.
sumber
PHP,
8684 karakterDengan array diinisialisasi, kita mulai menghitung:
Prettified:
Item terakhir dalam daftar dimodifikasi. Ini harus OK karena dalam PHP, tugas array dan panggilan fungsi melakukan salinan.
sumber
CJam,
35302827 byteIni adalah program yang membaca dari STDIN dan mencetak ke STDOUT. Cobalah online.
Bagaimana itu bekerja
Contoh dijalankan
sumber
Google Sheets,
67686792 byteInput dimulai pada sel
A1
dan terus turun untuk banyak entri yang ada.JOIN
menggabungkan mereka semua menjadi string dengan koma-ruang di antara masing-masing.FILTER
menghapus non-kosong sehingga Anda tidak berakhir dengan koma tak terbatas di akhir.SUBSTITUTE
menggantikan koma terakhir (ditemukan denganCOUNTA
menghitung input yang tidak kosong).Ini tidak terlalu menarik tetapi bisa dilakukan dalam satu sel.
sumber
)
dari rumus ini untuk -1 Byte; Ya ampun, itu edit tercepat yang pernah saya lihat +1A:A>""
harus dikonversi keA:A<>""
dan ini tidak menerapkan menghilangkan koma oxford pada kasus hanya 2 objek>""
. Koreksi kilat yang saya buat sebelumnya jelas tidak diuji. Saya tidak suka arah yang menuju ...JavaScript (ES6) 60
Dengan asumsi tidak ada string kosong dalam array input
Tes di konsol FireFox / Firebug
Keluaran
sumber
node --harmony
dengan berbagai stringvar a = 'abcdefgh'.split('');
, tetapi hanya duduk di sana dengan...
dan tampaknya tidak melakukan apa-apa. Juga memberi +1 untuk menggunakan fitur ES6 yang unik()=>
.f=(a,b=a.pop())=>a[0]?a.join(', ')+', and '+b:b
juga benar dan 13 byte lebih pendek.JavaScript -
6056716763Bukan pendekatan idiomatis, tapi saya senang menulisnya dan saya suka regex.
Dengan asumsi array disimpan di
var a
:Dipersingkat dengan hanya memeriksa indeks
[2]
: (yay boolean coercion)Rupanya saya payah dalam pengujian dan melewatkan tes satu entri. Ini versi yang sudah diperbaiki:
Mencukur 2 karakter dengan membalikkan boolean saya dan 3 lainnya dengan memindahkan ruang dari penggabungan ke saat itu / yang lain di ternary pertama:
Terima kasih kepada @tomsmeding karena mengingatkan saya bahwa saya tidak perlu memaksa boolean saya karena JS melakukan itu untuk saya. Saya juga menyadari bahwa saya lupa menghapus tanda kurung yang memisahkan terner pertama dari rangkaian di dalam
join()
:Apakah saya melakukan itu dengan benar? Permintaan pegolf baru yang wajib.
sumber
!!
sama sekali;a[2]?A:B
sudah bekerja. Mungkin harus membalikkan boolean Anda lagi .a[i]
sama dengan true . Hampir saja. Saya berasumsi bahwa jika Anda mendapatkan 2 input, array Anda memiliki panjang dua. Kemudiana[2]===undefined
danundefined
mengevaluasi kefalse
. Sunting: suntingan Anda adalah yang saya maksud :)Golfscript -
31393430Halo Dunia! Saya lama bersembunyi, poster pertama kali. Berikut adalah solusi 30 byte saya di Golfscript (diberikan array seperti [1 2 3] sudah ada di stack).
Hasilnya tepat untuk semua kasus uji.
EDIT: Ambil itu, CJam!
sumber
Xojo,
527183 karakterPerhatikan bahwa UBound kurang dari panjang array.
sumber
Excel VBA, 108 Bytes
Fungsi jendela langsung VBE anonim yang mengambil input sebagai array yang dibatasi ruang dari rentang
A1
dan keluaran ke jendela langsung VBE.sumber
Raket 87
sumber
Python 62 chars
Dengan asumsi bahwa saya adalah daftar string:
sumber
C # 102 Chars
sumber
Julia (53)
Membawa args dari STDIN dan output ke STDOUT
Solusi menggunakan Base.join (item, delim [, terakhir])
Edit:
Uji kasus
1
1 dan 2
1, 2, dan 3
sumber
1, 2, and 3
tidak1, 2 and 3
.Kata-kata kasar (108)
Tidak Disatukan:
Pemakaian:
Cobalah online
sumber
Pyth, 28
Contoh:
sumber
TypeError: can only concatenate list (not "str") to list
) saya. Ini berfungsi dengan baik dengan versi terbaru.PHP - 72
Siapkan input:
Dan kemudian prosesnya:
sumber