What is better to use for mapping value to Map of functions: tail recursion or foreach? I want to map functions from my functions library (Map called as chain) to input string str. Also that functions (Twitter.removeRT, ...) are regex which replace substrings in input str. I think it is better to save that regex-functions in Map like in my example.

So, the code:

Tail recursion variant

  def filterTwitter2 (str: String): String = {

    @scala.annotation.tailrec
    def recFilter(str: String, chain: Map[String, (String) =&gt; String]): String = {
      chain.headOption match {
        case Some(v) =&gt;
          val filteredString = v._2(str)
          recFilter(filteredString, chain.tail)
        case None =&gt; str
      }
    }

    val chain = Map[String,(String) =&gt; String](
      "f1"-&gt; Twitter.removeRT,
      "f2"-&gt; Twitter.removeNickName,
      "f3"-&gt; Twitter.removeURL,
      "f6"-&gt; Emoticons.removePunctRepetitions,
      "f7"-&gt; Emoticons.removeHorizontalEmoticons,
      "f9"-&gt; Emoticons.normalizeEmoticons,
      "f10"-&gt; Beautify.removeCharRepetitions,
      "f12"-&gt; Beautify.removeNSpaces
    )

    recFilter(str, chain)
  }


foreach variant

  def filterTwitter (str: String): String = {
    var tmp = str
    val chain = Map[String,(String) =&gt; String](
      "f1"-&gt; Twitter.removeRT,
      "f2"-&gt; Twitter.removeNickName,
      "f3"-&gt; Twitter.removeURL,
      "f6"-&gt; Emoticons.removePunctRepetitions,
      "f7"-&gt; Emoticons.removeHorizontalEmoticons,
      "f9"-&gt; Emoticons.normalizeEmoticons,
      "f10"-&gt; Beautify.removeCharRepetitions,
      "f12"-&gt; Beautify.removeNSpaces
    )
    chain.foreach {
      case (name, func) =&gt; tmp = func(tmp)
    }
    tmp
  }


So, the questions:


Is it normal to save functions in map? What can be better for it? 
What better: tail recursion variant or variant with foreach?
Maybe there is any better solution for that problem?
You never use your Map to lookup a filter function by its key. If you don't need any of the keys then you don't really need a Map.

def filterTwitter(str :String) :String =
  List(Twitter.removeRT
      ,Twitter.removeNickName
      ,Twitter.removeURL
      ,Emoticons.removePunctRepetitions
      ,Emoticons.removeHorizontalEmoticons
      ,Emoticons.normalizeEmoticons
      ,Beautify.removeCharRepetitions
      ,Beautify.removeNSpaces
      ).foldRight(str)(_(_))




EXPLANATION

The 1st underscore is an element from the List that is being folded. Because this is a fold Right, it will start with the last element (removeNSpaces) and work toward the head (removeRT).

The 2nd underscore is the result from the previous invocation and it is being passed as an argument to the filter function. (Actually it's a little more complicated than that, but this is an easy way to think about it.)

So this is what's going down:

removeNSpaces(str)             ===&gt; resStr1
removeCharRepetitions(resStr1) ===&gt; resStr2
normalizeEmoticons(resStr2)    ===&gt; resStr3
. . .
removeRT(prevResStr)           ===&gt; finalResStr