Reputation: 16718
Suppose there are 3 strings:
protein, starch, drink
Concatenating those, we could say what is for dinner:
Example:
val protein = "fish"
val starch = "chips"
val drink = "wine"
val dinner = protein + ", " + starch + ", " + drink
But what if something was missing, for example the protein, because my wife couldn't catch anything. Then, we will have: ,chips, drink
for dinner.
There is a slick way to concatenate the strings to optionally add the commas - I just don't know what it is ;-). Does anyone have a nice idea?
I'm looking for something like:
val dinner = protein +[add a comma if protein is not lenth of zero] + starch .....
It's just a fun exercise I'm doing, so now sweat if it can't be done in some cool way. The reason that I'm trying to do the conditional concatenation in a single assignment, is because I'm using this type of thing a lot in XML and a nice solution will make things..... nicer.
Upvotes: 28
Views: 33499
Reputation: 13221
When you say "it may be absent", this entity's type should be Option[T]
. Then,
def dinner(components: List[Option[String]]) = components.flatten mkString ", "
You would invoke it like this:
scala> dinner(None :: Some("chips") :: Some("wine") :: Nil)
res0: String = chips, wine
In case you absolutely want checking a string's emptiness,
def dinner(strings: List[String]) = strings filter {_.nonEmpty} mkString ", "
scala> dinner("" :: "chips" :: "wine" :: Nil)
res1: String = chips, wine
Upvotes: 40
Reputation: 489
This takes care of the case of empty strings and also shows how you could put other logic for filtering and formatting. This will work fine for a List[String]
and generalizes to List[Any]
.
val input = List("fish", "", "chips", 137, 32, 32.0, None, "wine")
val output = input.flatMap{ _ match {
case None => None
case x:String if !x.nonEmpty => None
case x:String => Some(x)
case _ => None
}}
.mkString(",")
res1: String = fish,chips,wine
The idea is that flatMap
takes a List[Any]
and uses matching to assign None
for any elements that you do not want to keep in the output. The Nones get flattened away and the Somes stay.
If you needed to be able to handle different types (Int, Double, etc) then you could add more cases.
Upvotes: 5
Reputation: 297205
scala> def concat(ss: String*) = ss filter (_.nonEmpty) mkString ", "
concat: (ss: String*)String
scala> concat("fish", "chips", "wine")
res0: String = fish, chips, wine
scala> concat("", "chips", "wine")
res1: String = chips, wine
scala>
Upvotes: 13
Reputation: 36229
You're looking for mkString on collections, maybe.
val protein = "fish"
val starch = "chips"
val drink = "wine"
val complete = List (protein, starch, drink)
val partly = List (protein, starch)
complete.mkString (", ")
partly.mkString (", ")
results in:
res47: String = fish, chips, wine
res48: String = fish, chips
You may even specify a start and end:
scala> partly.mkString ("<<", ", ", ">>")
res49: String = <<fish, chips>>
Upvotes: 14