How to get single line semicolon oxford in groovy?

I'm new to Groovy and trying to figure out some idioms that make him attractive. For example, I would like to take a list of strings and return one correctly labeled string created from a list, with each item being quoted.

Roughly speaking, a literal (rather general and probably brain) approach would be

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 } 

Is there a Groovy way of doing this to use language idioms?

+2
string list coding-style groovy
source share
4 answers

Take a look at my solution below. It seems to be difficult at first sight, but it is quite simple. Feel free to ask if you have any questions.

 def oxfordComma(list) { list = list.collect { "'$it'" } list.size in [1,2] ? list.join(' and ') : list[0..-2].join(', ') + ', and ' + list[-1] } assert oxfordComma(['one']) == "'one'" assert oxfordComma(['one', 'two']) == "'one' and 'two'" assert oxfordComma(['one', 'two', 'three']) == "'one', 'two', and 'three'" 

And a shorter version for code golf below; -)

 oxfordComma = { list -> list.collect{"'$it'"}.with { it.size in [1,2] ? it.join(' and ') : it[0..-2].join(', ') + ', and ' + it[-1] } } 
+1
source share

Too long but hey:

 oxford = { list -> list.collect { "'$it'" }.with { size() > 1 ? (take(size() - 1) << "and " + last()).join(size() == 2 ? " " : ", ") : it[0] } } assert oxford(["a", "b"]) == "'a' and 'b'" assert oxford(["a"]) == "'a'" assert oxford(["a", "b", "c"]) == "'a', 'b', and 'c'" 

Feels like a golf course :-)

+1
source share

take excellent, but the range is shorter. using the same code for switch case 1 and case 2 turns the switch into an if value. with saves temp-var.

  def oxford = { it.collect({"'$it'"}).with{ it.size() < 3 ? it.join(' and ') : "${it[0..-2].join(', ')}, and ${it[-1]}" } } assert oxford(['Larry']) == '\'Larry\'' assert oxford(['Larry', 'Jeff']) == '\'Larry\' and \'Jeff\'' assert oxford(['Larry', 'Jeff', 'Leon']) == '\'Larry\', \'Jeff\', and \'Leon\'' 
+1
source share

(This question is quite subjective for Stack O.)

My answer uses metaclass functionality (and other minor functions). The solution is not short in implementation, but is short in use (and idiomatic, in the sense of writing a structure):

 a=['oxford','cambridge'] println a.toString() *prints* >> 'oxford' and 'cambridge' 

Decision:

 // quote def q = {"'$it'"} // apply Oxford for N > 2 def f = {it[0..-2].join(", ") + ", and " + it[-1]} // map list size to Oxford function (N > 2 is default) def fmap = [:].withDefault{f} fmap[0] = {""} fmap[1] = {"${it[0]}"} fmap[2] = {"${it[0]} and ${it[1]}"} // re-define toString() to call Oxford function from map // (with quoted items) ArrayList.metaClass.toString = { -> fmap[ delegate.size() ].call( delegate.collect{q(it)} ) } 

Usage example:

 a=[] ; println a.toString() a=['oxford'] ; println a.toString() a=['oxford','cambridge'] ; println a.toString() a=['oxford','cambridge','comma','space'] ; println a.toString() 

Output from examples (_ denotes an empty string):

 _ 'oxford' 'oxford' and 'cambridge' 'oxford', 'cambridge', 'comma', and 'space' 
0
source share

All Articles