[Question]
  [
What are some clever (brief and idiomatic) approaches to taking a list of strings and returning a single properly punctuated string built from the list, with each element quoted.
This came up for me while [experimenting with Groovy](https://stackoverflow.com/q/25793522/656912), for which my too-literal, but illustrative solution is
```
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
}
```
That is, `['1']` should yield `'1'`, `['1','2']` should yield `'1 and 2'`, [see what I did there?] and `['1','2','3']` should yield `'1, 2, and 3'`.
I have some good answers for Groovy, but I'd like to see what other languages can do.
What are some *compact* clever approaches in various languages that take advantage of the features and idioms of those languages?
  
[Answer]
# 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 "
```
```
<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 is not seen too often in code golf because it can only format text, but it actually works for this challenge and I thought it would be fun to do. See it in action using the snippet above (click "Show code snippet").
List should be in a linked HTML file with each element surrounded by `<a>` tags and separated by line breaks. The list items should be the only elements in their parent element, e.g.
```
<a>one</a>
<a>two</a>
<a>three</a>
```
## Explanation
```
a:not(:last-child):nth-child(n+2)::after,
a:nth-last-child(n+3)::after {
    content: ",";
}
a + :last-child::before {
    content: "and ";
}
```
Let's consider the ungolfed version above. If you're not familiar with how CSS works, everything outside the curly braces is a selector that determines the set of HTML elements to which the declarations inside the braces apply. Each selector-declaration pair is called a *rule*. (It's more complicated than that but will suffice for this explanation.) Before any styling is applied, the list appears separated by only spaces.
We want to add commas after every word except the last, except for two-word lists, which get no commas. The first selector, `a:not(:last-child):nth-child(n+2):after`, selects all elements except the first and the last. `:nth-child(n+2)` is a shorter way of saying `:not(:first-child)`, and it basically works by selecting elements whose index (starting at 1) is greater than or equal to 2. (Yes, it still confuses me a little. The [MDN docs](https://developer.mozilla.org/en-US/docs/Web/CSS/:nth-child) might help.)
Now we just need to select the first element to get a comma *if* there are three or more elements total. `a:nth-last-child(n+3):after` works like `:nth-child`, but counting from the back, so it selects all elements except the last two. The comma takes the union of the two sets, and we use the `:after` [pseudo-element](https://developer.mozilla.org/en-US/docs/Web/CSS/::after) to add `content` immediately after each selected element.
The second rule is easier. We need to add "and" before the last element in the list, unless it is a single element. In other words, we need to select the last element that is preceded by another element. `+` is the [adjacent sibling selector](https://developer.mozilla.org/en-US/docs/Web/CSS/Adjacent_sibling_selectors) in CSS.
[Answer]
# Haskell: ~~81, 77~~ 74 chars
```
f[x]=x
f[x,y]=x++" and "++y
f[x,y,z]=x++", "++f[y++",",z]
f(x:y)=x++", "++f y
```
Haskell features: Pattern matching
[Answer]
## Ruby, 47 bytes
```
q=" and ";p$*[2]?(a=$*.pop;$**", "+?,+q+a):$**q
```
### Explanation
* The input are the command line arguments (`$*`).
* When `$*` has a third element (`$*[2]` does not return nil), take all elements minus the last one and turn them into a comma-separated String using `Array#*`. Finally add an extra comma, the string `" and "` and the last command line argument.
* When `$*` has no third element, two, one, or zero arguments were given. The arguments can safely be joined with the string `" and "` and produce the correct result.
[Answer]
# Python 2 (61)
```
s=input()
d=s.pop()
print", ".join(s)+", and "[8-7*len(s):]+d
```
The main trick is to cut off part of the final joiner `", and "` for one and two elements. For one, all of it is cut out, and for two, the comma is removed. This is done by slicing out `[8-7*len(s):]` (noting that `s` is one shorter after the `pop`).
Unfortunately, `d` cannot just be replaced with its expression or the `pop` would happen too late. 
[Answer]
# CSS, ~~62 chars~~ 112 chars
Inspired by the other entries, even shorter. Note that it requires that A elements are not separated by white spaces:
```
a+a:before{content:", "}a+a:last-child:before{content:", and "
```
<http://jsfiddle.net/olvlvl/1Ls79ocb/>
Fix for the "one and two", as pointed at by Dennis:
```
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/>
[Answer]
# Perl (v 5.10+) - ~~37~~ ~~35~~ ~~34~~ 28
```
@F>2&&s/ /, /g;s/.* \K/and /
```
to be run with `perl -ape`, with the list supplied space separated on `STDIN`.
Output for various inputs:
```
$ 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
```
[Answer]
# Javascript (63)
`l=a.length;l>2&&(a[l-1]='and '+a[l-1]);a.join(l>2?', ':' and ')`
Cases:
* `a = [1]` => `1`
* `a = [1, 2]` => `1 and 2`
* `a = [1, 2, 3]` => `1, 2, and 3`
Caveat: this will modify the last element in an array with length > 2.
[Answer]
# GNU sed - 69 chars including 1 for `-r` flag
```
s/ /, /g
s/( [^ ]+)( [^ ]+)$/\1 and\2/
s/^([^,]+),([^,]+)$/\1 and\2/
```
Takes a space-separated list (fairly idiomatic for shell scripts).
## Example
```
$ 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
$
```
[Answer]
# Python 2 - ~~71, 70~~ 68
```
s=input()
l=len(s)-1
print', '.join(s[:l])+', and '[l<2:]*(l>0)+s[l]
```
Character count including both, `input` and `print`.
[Answer]
## Ruby, 57 bytes
```
f=->l{s=l*', ';s.sub(/,(?!.*,)/,(l.size<3?'':?,)+' and')}
```
I'm joining the string with `,` and then I'm replacing the last comma in the string with an `and` (and optional comma depending on list length).
[Answer]
# Cobra - 60
```
do(l as String[])=l.join(', ',if(l.length<3,'',',')+' and ')
```
Cobra's `List<of T>.join` function lets you specify a different separator for the final two elements of the list, which is what makes this so short.
[Answer]
# Perl - 59
```
sub f{$a=join', ',@_;$#_&&substr$a,(@_>2)-3,@_<3,' and';$a}
```
Joins the list with commas, then if the list has more than one element, either adds `' and'` after the last comma (if length >= 3), or replaces the last comma with it (if length == 2).
[Answer]
# PHP, ~~192~~ ~~167~~ ~~146~~ 136 characters:
```
$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)))));
```
Based on a function I wrote years ago at <http://www.christopherbloom.com/2011/05/21/join-implode-an-array-of-string-values-with-formatting/>
[Answer]
## 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!
```
Note; you have to call the script from `cmd` with the `/v` switch set as `on`, this is so I don't have to include the lengthy `setLocal enableDelayedExpansion` in the script. Otherwise add 30 to the byte count, and call the script normally.
```
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
```
[Answer]
## Groovy, ~~47 43~~ 57 characters , JavaScript ES6 56 characters
**Groovy:**
```
(a[1]?a[0..-2].join(", ")+(a[2]?",":"")+" and ":"")+a[-1]
```
Since the array is filled with characters, we can replace `a.size>1` by `a[1]`
**JavaScript, ES6:**
```
a.join(', ').replace(/,([^,]+)$/,`${a[2]?',':''} and$1`)
```
Both cases assume that variable a has the array in question.
[Answer]
# PHP, ~~86~~ 84 chars
```
$a = ['one', 'two', 'three', 'four', 'five'];
```
With the array initialized, we start counting:
```
$L=count($a)-1;$S=', ';$L<2?($S=' and '):($a[$L]='and '.$a[$L]);echo implode($S,$a);
```
Prettified:
```
$last_index = count($a) - 1;
$separator = ', ';
if ($last_index < 2) {
    $separator = ' and ';
} else {
    $a[$last_index] = 'and '.$a[$last_index];
}
echo implode($separator, $a);
```
The last item in the list is modified. This should be OK because in PHP, array assignment and function calls perform copies.
[Answer]
# CJam, ~~35~~ ~~30~~ ~~28~~ 27 bytes
```
q~)\_"and "L?@+a+_,2=", ">*
```
This is a program that reads from STDIN and prints to STDOUT. [Try it online.](http://cjam.aditsu.net/ "CJam interpreter")
### How it works
```
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)                               ";
```
### Example run
```
$ 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
```
[Answer]
# Google Sheets, ~~67~~ ~~68~~ ~~67~~ 92 bytes
```
=SUBSTITUTE(JOIN(", ",FILTER(A:A,A:A<>"")),",",IF(COUNTA(A:A)>2,",","")&" and",COUNTA(A:A)-1
```
The input starts at cell `A1` and continuing down for however many entries exist.  
`JOIN` merges them all into a string with a comma-space between each.  
`FILTER` removes any non-blanks so you don't end up with infinite commas at the end.  
`SUBSTITUTE` replaces the last comma (found by `COUNTA` counting the non-blank inputs).
It's not very exciting but it's doable in a single cell.
[Answer]
# [Vyxal](https://github.com/Vyxal/Vyxal), 27 bytes
```
ṫ$:[`λ¬ `pJ:Ḣ₃[÷ð$Ṡ|‛, j]|_
```
[Try it Online!](https://lyxal.pythonanywhere.com?flags=&code=%E1%B9%AB%24%3A%5B%60%CE%BB%C2%AC%20%60pJ%3A%E1%B8%A2%E2%82%83%5B%C3%B7%C3%B0%24%E1%B9%A0%7C%E2%80%9B%2C%20j%5D%7C_&inputs=%5B1%5D&header=&footer=)
```
ṫ                           # Tail extract (x[:-1], x[-1] )
 $:[                        # If length > 1
    `λ¬ `p                  # Prepend a 'and '
          J                 # Merge
           :Ḣ₃[             # If length = 2
               ÷ð$Ṡ         # Add in a space and join
                   |    ]   # Else...
                    ‛, j    # Join by ', '
                         |_ # Else pop
```
[Answer]
# JavaScript (ES6) 60
Assuming no empty strings in input array
```
f=(a,b=a.pop())=>a[0]?a.join(', ')+(a[1]?',':'')+' and '+b:b
```
**Test** In FireFox/Firebug console
```
console.log(f(['We invited the stripper','JFK','Stalin']))
```
*Output*
```
 We invited the stripper, JFK, and Stalin
```
[Answer]
# JavaScript - ~~60~~ ~~56~~ ~~71~~ ~~67~~ 63
Not exactly an idiomatic approach, but I had fun writing it and I like regex.
Assuming the array is stored in `var a`:
```
a.join((a.length>2?',':'')+' ').replace(/([^,\s])$/,"and $1")
```
Shortened by simply checking for index `[2]`: (yay boolean coercion)
```
a.join((!!a[2]?',':'')+' ').replace(/([^,\s])$/,'and $1')
```
Apparently I suck at testing and skipped a single-entry test. Here's the fixed version:
```
a.join((!!a[2]?',':'')+' ').replace(/([^,\s])$/,(!!a[1]?'and ':'')+'$1')
```
Shaved off 2 chars by inverting my booleans and 3 more by moving the space from the concatenation into the then/else of the first ternary:
```
a.join((!a[2]?' ':', ')).replace(/([^,\s])$/,(!a[1]?'':'and ')+'$1')
```
Thanks to @tomsmeding for reminding me that I don't have to coerce my booleans because JS does that for me. I also realised I forgot to remove the parentheses separating the first ternary from the concatenation inside the `join()`:
```
a.join(a[2]?', ':' ').replace(/([^,\s])$/,(a[1]?'and ':'')+'$1')
```
Did I do that right? Obligatory new golfer apology.
[Answer]
## Golfscript - 31 39 34 30
Hello, World! I am a long time lurker, first time poster. Here is my 30 byte solution in Golfscript (given the array such as [1 2 3] is already on the stack).
```
.,3<" and ":A{~A(;\+]", "}if*
```
The results are proper for all test cases.
EDIT: Take that, CJam!
[Answer]
# Xojo, ~~52~~ ~~71~~ 83 chars
```
dim i as int8=ubound(L)
L(i)=if(i=0,"","and ")+L(i)
Return L.Join(if(i=1," ",", ")
```
Note that UBound is one less than the array length.
[Answer]
# Excel VBA, 108 Bytes
Anonymous VBE immediate window function that takes input as space delimited array from range `A1` and outputs to the VBE immediate window.
```
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]
```
[Answer]
# Racket 87
```
(define(f x)(string-join(map ~a x)", "#:before-last(if(= 2(length x))" and "", and ")))
```
[Answer]
# Python 62 chars
Assuming that i is the list of strings:
```
(" and", ", and")[len(i) < 2].join(", ".join(i).rsplit(",",1))
```
[Answer]
**C# 102 Chars**
```
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;
```
[Answer]
# Julia (53)
```
print(join(ARGS,", ",(endof(ARGS)>2?",":"")" and "))
```
Takes args from STDIN and outputs to STDOUT
Solution using Base.join(items, delim[, last])
Edit:
Test cases
```
julia oxfordComma.jl 1
```
1
```
julia oxfordComma.jl 1 2
```
1 and 2
```
julia oxfordComma.jl 1 2 3
```
1, 2, and 3
[Answer]
# 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
]
```
Usage:
```
[$l:{A|B|C|D|E}]
```
[Try it online](http://berkin.me/rantbox#6734D3D88CF16B473F6BE7F4CAF8586B36E0AFAE)
[Answer]
# Pyth, 28
```
j>", "qlQ2+_t_Q+?"and "tQkeQ
```
### Examples:
```
$ 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
```
]