Fork me on GitHub

Graceless Failures

Tips, tricks, missteps, and minor revelations on the path to Scala wisdom.

Compacting Java Code, and Style

An unnamed library included this joyous piece of sample code (please ignore the gratuitous style violations — they were clearly C++ coders):

public String[] getPrefixes(String prefix) {
  Vector<string> v = new Vector<string>();
  for(String s : map.keySet())
  {
    if(s.startsWith(prefix) && !s.equals(prefix))
    {
        v.add(s);
    }
  }

  if(v.size() > 0)
  {
    return (String[])v.toArray(new String[0]);
  }
  else
  {
    return null;
  }
}

I thought, “This is a place where Scala can shine. Let’s try to remove the 99% of this code that’s just boilerplate.” Here’s what I came up with:

def getPrefixes(prefix: String): Array[String] = {
  val keyList = (for (val key <- map.keys if key.startsWith(prefix) && (key != prefix)) yield key).toList
  if (keyList.size > 0) keyList.toArray else null
}

But wait. That’s really terse, but doesn’t look awesome. The first line is too long to completely absorb when skimming, and the last line is questionable style — I wanted a Ruby-style keyList.toArray unless keyList.empty? but Scala uses inline if/else for the a ? b : c operator so it looks weird. Second try, let’s use matching instead:

def getPrefixes(prefix: String): Array[String] = {
  (for (val key <- map.keys if key.startsWith(prefix) && (key != prefix)) yield key).toList match {
    case Nil => null
    case list => list.toArray
  }
}

That works. The (…).toList construct still bothers me a bit though. Is there some better way to do that?