The most idiomatic way to perform conditional concatenation of strings in Scala

I'm curious what would be the best way to build a String value via sequential appending of text chunks, if some of chunks dynamically depend on external conditions. The solution should be idiomatic for Scala without much speed and memory penalties.

For instance, how one could re-write the following Java method in Scala?

public String test(boolean b) {
    StringBuilder s = new StringBuilder();
    s.append("a").append(1);
    if (b) {
        s.append("b").append(2);
    }
    s.append("c").append(3);
    return s.toString();
}

Upvotes: 9

Views: 8470

Answers (5)

Scott Carey
Scott Carey

Reputation: 1647

These days, idiomatic means string interpolation.

s"a1${if(b) "b2" else ""}c3"

You can even nest the string interpolation:

s"a1${if(b) s"$someMethod" else ""}"

Upvotes: 9

Mark
Mark

Reputation: 607

In scala, a String can be treated as a sequence of characters. Thus, an idiomatic functional way to solve your problem would be with map:

"abc".map( c => c match {
  case 'a' => "a1"
  case 'b' => if(b) "b2" else ""
  case 'c' => "c3"
  case _ =>
}).mkString("")

Upvotes: 2

Russell
Russell

Reputation: 12439

What about making the different components of the string functions in their own right? They have to make a decision, which is responsibility enough for a function in my book.

def test(flag: Boolean) = {
  def a = "a1"
  def b = if (flag) "b2" else ""
  def c = "c3" 
  a + b + c
}

The added advantage of this is it clearly breaks apart the different components of the final string, while giving an overview of how they fit together at a high level, unencumbered by anything else, at the end.

Upvotes: 5

Nikita Volkov
Nikita Volkov

Reputation: 43310

Since Scala is both functional and imperative, the term idiomatic depends on which paradigm you prefer to follow. You've solved the problem following the imperative paradigm. Here's one of the ways you could do it functionally:

def test( b : Boolean ) =
  "a1" + 
  ( if( b ) "b2" else "" ) +
  "c3"

Upvotes: 13

pagoda_5b
pagoda_5b

Reputation: 7373

As @om-nom-nom said, yours is already sufficiently idiomatic code

def test(b: Boolean): String = {
  val sb = new StringBuilder
  sb.append("a").append(1)
  if (b) sb.append("b").append(2)
  sb.append("c").append(3)
  sb.toString
}

I can suggest an alternative version, but it's not necessarily more performant or "scala-ish"

def test2(b: Boolean): String = "%s%d%s%s%s%d".format(
  "a", 
  1,
  if (b) "b" else "",
  if (b) 2 else "",
  "c",
  3)

Upvotes: 2

Related Questions