2

あなたが持っているとしましょう:

List(('a', 1), ('b', 1), ('c', 1), ('b', 1))

('b', 1)そして、最初のものをに置き換え、('b', 2)(a) 最初の一致を過ぎて評価するのに時間を浪費したり、(b) それ以降の一致するタプルを更新したりしたくありません。

Scala でこれを行う比較的簡潔な方法はありますか (つまり、リストを分解して再連結せずに)。mapFirst最初に一致する値がインクリメントされたリストを返す架空の関数のようなもの:

testList.mapFirst { case ('b', num) => ('b', num + 1) }

4

3 に答える 3

3

リスト全体をバラバラにする必要はありません。(要素が見つかるまでのみ)

def replaceFirst[A](a : List[A], repl : A, replwith : A) : List[A] = a match {
  case Nil => Nil
  case head :: tail => if(head == repl) replwith :: tail else head :: replaceFirst(tail, repl, replwith) 
}

たとえば、呼び出し:

replaceFirst(List(('a', 1), ('b', 1), ('c', 1), ('b', 1)), ('b', 1), ('b', 2))

結果:

List((a,1), (b,2), (c,1), (b,1))

部分関数と暗黙の方法 (mapFirst のように見えます):

implicit class MyRichList[A](val list: List[A]) {
    def mapFirst(func: PartialFunction[A, A]) = {
      def mapFirst2[A](a: List[A], func: PartialFunction[A, A]): List[A] = a match {
        case Nil => Nil
        case head :: tail => if (func.isDefinedAt(head)) func.apply(head) :: tail else head :: mapFirst2(tail, func)
      }
      mapFirst2(list, func)
    }
}

そして、次のように使用します。

List(('a', 1), ('b', 1), ('c', 1), ('b', 1)).mapFirst {case ('b', num) => ('b', num + 1)}
于 2013-10-29T01:04:45.780 に答える