1
votes

I want the following function: taking the following parameters:

  • def filters: Map[String, String]
  • def queryString: Map[String, Seq[String]] (from request.queryString)
  • def key: String

.. if queryString contains the key specified in parameter, I want to add the corresponding value to filters.

A working function is:

private def getUpdatedFiltersIfQueryStringContains(filters: Map[String, String], queryString: Map[String, Seq[String]], key: String): Map[String, String] = {
  var updatedFilters: Map[String, String] = filters

  if (queryString.contains(key)) {
    updatedFilters = updatedFilters ++ Map(key -> queryString.get(key).get.head)
  }

  updatedFilters
}

This looks horrendous, right?

Since if statements return stuff in Scala, I was expecting something more along those lines:

private def getUpdatedFiltersIfQueryStringContains(filters: Map[String, String], queryString: Map[String, Seq[String]], key: String): Map[String, String] = {
  if (queryString.contains(key)) {
    filters ++ Map(key -> queryString.get(key).get.head)
  }
}

But this doesn't compile, the error is:

type mismatch; found : Unit required: Map[String,String]

3
Scala does not a an if-statement - it has an if-expression. As you already said, they return a value - a statement is the name for an instruction that doesn't return anything.kiritsuku

3 Answers

5
votes

You can use the more monadic

queryString.get(key) map { v => filters ++ Map(key -> v.head) } getOrElse filters

which does what you want.

5
votes

Here is a more idiomatic implementation that doesn't use if:

def getUpdatedFiltersIfQueryStringContains(filters: Map[String, String], queryString: Map[String, Seq[String]], key: String): Map[String, String] =
  filters ++ queryString.get(key).map(key -> _.head)
4
votes

Your function signature states that Map[String, String] should be returned, but ... hold on a second and imagine, what if queryString doesn't contain a key? Well, looks like nothing will be returned, and Unit is nothing in Scala (at least one of the nothing kinds).

To fix that problem you need to provide alternative:

private def getUpdatedFiltersIfQueryStringContains(filters: Map[String, String], queryString: Map[String, Seq[String]], key: String): Map[String, String] = {
    if (queryString.contains(key)) {
      filters ++ Map(key -> queryString.get(key).get.head)
    } else filters
  }

by the way, function name really scares me