5

次のようなことを達成したい:

(_ : Map[K,Int]).mapKey(k, _ + 1)

そして、このmapKey関数は 2 番目の引数 ( Int => Int) を に格納されている値にのみ適用しkます。標準ライブラリ内に何かありますか? そうでなければ、Scalaz には何かがあるに違いない。

もちろん、この関数を自分で書くこともできますし ( m.updated(k,f(m(k)))、それを行うのは簡単です。しかし、私はこの問題に何度か遭遇したので、おそらくすでに完了していますか?

Scalaz の場合、次のコードに沿って何かを想像します。

(m: Map[A,B]).project(k: A).map(f: B => B): Map[A,B]
4

3 に答える 3

3

これが1つの方法です:

scala> val m = Map(2 -> 3, 5 -> 11)
m: scala.collection.immutable.Map[Int,Int] = Map(2 -> 3, 5 -> 11)

scala> m ++ (2, m.get(2).map(1 +)).sequence
res53: scala.collection.immutable.Map[Int,Int] = Map(2 -> 4, 5 -> 11)

scala> m ++ (9, m.get(9).map(1 +)).sequence
res54: scala.collection.immutable.Map[Int,Int] = Map(2 -> 3, 5 -> 11)

これは、(A, Option[B]).sequenceを与えるために機能しますOption[(A, B)]。(sequence一般に、タイプを裏返しにします。つまりF[G[A]] => [G[F[A]]、与えられF : TraverseG : Applicative。)

于 2012-02-12T20:32:55.857 に答える
3

もちろん、追加することもできます

def changeForKey[A,B](a: A, fun: B => B): Tuple2[A, B] => Tuple2[A, B] = { kv =>
  kv match {
    case (`a`, b) => (a, fun(b))
    case x => x
  }
}

val theMap = Map('a -> 1, 'b -> 2)
theMap map changeForKey('a, (_: Int) + 1)
res0: scala.collection.immutable.Map[Symbol,Int] = Map('a -> 2, 'b -> 2)

ただし、これにより、メモリの再利用とアクセスに関する最適化が回避されます。

projectまた、提案された方法にジッパーを使用して、かなり冗長で非効率的な scalaz ソリューションを思いつきました。

theMap.toStream.toZipper.flatMap(_.findZ(_._1 == 'a).flatMap(elem => elem.delete.map(_.insert((elem.focus._1, fun(elem.focus._2)))))).map(_.toStream.toMap)

また

(for {
  z <- theMap.toStream.toZipper
  elem <- z.findZ(_._1 == 'a)
  z2 <- elem.delete
} yield z2.insert((elem.focus._1, fun(elem.focus._2)))).map(_.toStream.toMap)

おそらくほとんど役に立ちません。参考までに投稿してみます。

于 2012-01-11T16:19:08.423 に答える
1

古いマップに基づいて新しいマップを作成するように、これをポンピングできます。

class MapUtils[A, B](map: Map[A, B]) {
  def mapValueAt(a: A)(f: (B) => B) = map.get(a) match {
    case Some(b) => map + (a -> f(b))
    case None => map
  }
}

implicit def toMapUtils[A, B](map: Map[A, B]) = new MapUtils(map)

val m = Map(1 -> 1)
m.mapValueAt(1)(_ + 1)
// Map(1 -> 2)
m.mapValueAt(2)(_ + 1)
// Map(1 -> 1)
于 2012-01-12T04:56:41.170 に答える