web-dev-qa-db-ja.com

Scala:HashMapをデフォルト値で使用する

可変HashMapがあり、それをデフォルト辞書のように使用したいと思います。明らかな方法は、getOrElseを使用し、毎回デフォルト値を2番目の値として提供することです。ただし、デフォルト値は変わらないため、これは私のユースケースではやや洗練されていないようです。

var x = HashMap(1 -> "b", 2 -> "a", 3 -> "c")

println(x.getOrElse(4, "_")
println(x.getOrElse(5, "_"))
// And so on...
println(x.getOrElse(10, "_"))

未定義のキーにアクセスしようとすると、HashMapの作成時に設定されたデフォルト値が返されるように、HashMap(または同様のクラス)を作成する方法はありますか? HashMap.defaultは例外をスローするように設定されているだけですが、これを変更できるかどうか疑問に思います...

31
PythonPower

これを試して:

import collection.mutable.HashMap
val x = new HashMap[Int,String]()  { override def default(key:Int) = "-" }
x += (1 -> "b", 2 -> "a", 3 -> "c")

次に:

scala> x(1)
res7: String = b

scala> x(2)
res8: String = a

scala> x(3)
res9: String = c

scala> x(4)
res10: String = -
35
huynhjl

うわー、最後の回答をここに投稿してからちょうど1年後にこのスレッドにアクセスしました。 :-)

Scala 2.9.1。 mutable.MapにはwithDefaultValueメソッドが付属しています。 REPLセッション:

scala> import collection.mutable
import collection.mutable

scala> mutable.Map[Int, String]().withDefaultValue("")
res18: scala.collection.mutable.Map[Int,String] = Map()

scala> res18(3)
res19: String = ""
70
missingfaktor
scala> val x = HashMap(1 -> "b", 2 -> "a", 3 -> "c").withDefaultValue("-")
x: scala.collection.immutable.Map[Int,Java.lang.String] = Map((1,b), (2,a), (3,c))

scala> x(3)
res0: Java.lang.String = c

scala> x(5)
res1: Java.lang.String = -

編集:

にとって mutable.HashMap、次のことができます。

scala> import collection.mutable
import collection.mutable

scala> val x = new mutable.HashMap[Int, String] {
     |   override def apply(key: Int) = super.get(key) getOrElse "-"
     | }
x: scala.collection.mutable.HashMap[Int,String] = Map()

scala> x += (1 -> "a", 2 -> "b", 3 -> "c")
res9: x.type = Map((2,b), (1,a), (3,c))

scala> x(2)
res10: String = b

scala> x(4)
res11: String = -

これを行うより良い方法があるかもしれません。他の人が応答するのを待ちます。

1
missingfaktor

私はもっ​​とJava guy ...ですが、getOrElseが最終的なものではない場合、単にHasMapを拡張して次のようなものを提供してみませんか。

override def getOrElse(k: Int, default: String) = {
  return super.getOrElse(k,"_")
}

注:構文はおそらく台無しになりますが、うまくいけば、あなたはポイントを得るでしょう

0
Pablo Fernandez