I saw the following image on this Twitter page:
and immediately became curious, “How can I create something like that Ruby %Q
function in Scala, but where each line becomes a string in a list, i.e., a Seq[String]
?”
A “Q” interpolator
Thanks to the help of Karsten — see the Comments section below — we can do something very similar in Scala. With his solution we can write code like this:
val list = Q""" http://angel.co/mile-high-organics http://angel.co/kindara http://angel.co/precog http://angel.co/pivotdesk """
His terrific solution was a combination of my “First attempt at a solution” shown below, and Scala’s string interpolation syntax.
The solution
Cutting right to the chase, his solution looks like this:
implicit class QHelper(val sc : StringContext) { def Q(args : Any*): Seq[String] = { val strings = sc.parts.iterator val expressions = args.iterator var buf = new StringBuffer(strings.next) while(strings.hasNext) { buf append expressions.next buf append strings.next } buf.toString.split("\n") .toSeq .map(_.trim) .filter(_ != "") } }
My first attempt at a solution (the original/old code)
In my first attempt at a solution I couldn’t think of how to solve the problem without making the list of URLs a multiline string, so I ended up creating a Scala object with an apply
method that converts a multiline string to a sequence:
object Q { def apply(s: String): Seq[String] = s.split("\n") .toSeq .map(_.trim) .filter(_ != "") }
Technically, that code converts a multiline String
to a Seq[String]
.
I then tested that Q
object with this little driver program:
object MultilineStringToList extends App { val list = Q(""" http://angel.co/mile-high-organics http://angel.co/kindara http://angel.co/precog http://angel.co/pivotdesk """) list.foreach(println) }
which printed out this:
http://angel.co/mile-high-organics http://angel.co/kindara http://angel.co/precog http://angel.co/pivotdesk
That’s not quite as pretty as the Ruby code, but it’s close. IMHO, it’s also easier to read and type than this:
val list = List( "http://angel.co/mile-high-organics", "http://angel.co/kindara", "http://angel.co/precog", "http://angel.co/pivotdesk" )
Summary
In summary, if you wanted to see how to convert a multiline string to a list/sequence in Scala, or otherwise wanted a Q
class/function like this, I hope this is helpful. And again, thanks to Karsten for greatly improving my original code.