Let a Counter toy class, such as:
class Counter private( val next: Int, val str2int: Map[String,Int] ) { def apply( str: String ): (Int,Counter) = str2int get str match { case Some(i) => ( i, this ) case None => ( next, new Counter( next+1, str2int + (str -> next) ) ) } } object Counter { def apply() = new Counter( 0, Map() ) }
This class provides a mapping between a string and a natural number, the display is incremented lazily every time a new line is requested.
Then I can write a method that can convert Seq strings to Seq of Ints, updating the display during the crawl. The first implementation I got is foldLeft :
def toInt( strs: Seq[String], counter: Counter ): ( Seq[Int], Counter ) = strs.foldLeft( (Seq[Int](), counter) ) { (result, str) => val (i, nextCounter) = result._2( str ) ( result._1 :+ i, nextCounter ) }
This works as intended:
val ss = Seq( "foo", "bar", "baz", "foo", "baz" ) val is = toInt( ss, Counter() )._1
But I'm not very happy with the implementation of toInt . The problem is that I add up two different values. Is there a functional programming pattern to simplify implementation?
paradigmatic
source share