Функциональный шаблон для двойного сворачивания

Пусть игрушечный класс Counter , например:

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() )
}

Этот класс обеспечивает отображение между строкой и натуральным числом, отображение расширяется лениво каждый раз, когда запрашивается новая строка.

Затем я могу написать метод, который может преобразовать a Seq of Strings in a Seq of Ints, обновляющая отображение во время обхода. Первая реализация, которую я получил, - это 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 )
  }

Это работает как задумано:

val ss = Seq( "foo", "bar", "baz", "foo", "baz" )
val is = toInt( ss, Counter() )._1
            //is == List(0, 1, 2, 0, 2)

Но я не очень доволен toInt . Проблема в том, что я складываю два разных значения. Есть ли шаблон функционального программирования для упрощения реализации?

7
задан paradigmatic 24 August 2011 в 14:26
поделиться