在scala中跳过hash(hash)哈希的初始化?

时间:2013-10-20 23:38:00

标签: scala

如何避免初始化(第5和第6行)?

import scala.collection._
def newHash = mutable.Map[String,String]()
def newHoH = mutable.Map[String,mutable.Map[String,String]]()
var foo = mutable.Map[String,mutable.Map[String,mutable.Map[String,String]]]()
foo("bar") = newHoH          //line 5
foo("bar")("baz") = newHash  //line 6
foo("bar")("baz")("whee") = "duh"

我尝试使用一个更简单的例子来使用DefalValue,但显然我做错了:

/***
scala> var foo = mutable.Map[String,mutable.Map[String,String]]().withDefaultValue(mutable.Map(""->""))
foo: scala.collection.mutable.Map[String,scala.collection.mutable.Map[String,String]] = Map()

scala> foo("bar")("baz") = "duh"
scala> foo("b")("baz") = "der"
scala> foo("bar")("baz")
res7: String = der
*/

1 个答案:

答案 0 :(得分:0)

withDefault方法不起作用。每次没有密钥时,以这种方式创建的Map都会返回一个新地图,因此调用mymap("foo")("bar") = "ok"会将“ok”分配给临时创建的地图,但下次调用mymap("foo")("bar")时, "foo"上不存在的mymap密钥将导致创建新地图,该地图不会包含映射"foo" -> "bar"

相反,请考虑创建一个匿名地图。我展示了一个只有1个嵌套的解决方案:

‡ scala-version 2.10.1
Welcome to Scala version 2.10.1 (Java HotSpot(TM) Server VM, Java 1.7.0_21).
Type in expressions to have them evaluated.
Type :help for more information.

scala> import collection._
import collection._

scala> :paste
// Entering paste mode (ctrl-D to finish)

def newHash = mutable.Map[String,String]().withDefault(_ => "")

def newHoH = new mutable.Map[String,mutable.Map[String,String]]() {
  val m = mutable.Map[String, mutable.Map[String, String]]()
  def +=(kv: (String, mutable.Map[String, String])) = { m += kv; this }
  def -=(k: String) = { m -= k; this }
  def get(k: String) = m.get(k) match {
    case opt @ Some(v) => opt
    case None =>
      val v = newHash
      m(k) = v
      Some(v)
  }
  def iterator = m.iterator
}

// Exiting paste mode, now interpreting.

newHash: scala.collection.mutable.Map[String,String]
newHoH: scala.collection.mutable.Map[String,scala.collection.mutable.Map[String,String]]{val m: scala.collection.mutable.Map[String,scala.collection.mutable.Map[String,String]]}

scala> val m = newHoH
m: scala.collection.mutable.Map[String,scala.collection.mutable.Map[String,String]]{val m: scala.collection.mutable.Map[String,scala.collection.mutable.Map[String,String]]} = Map()

scala> m("foo")("bar") = "ok"

scala> m("foo")("bar")
res1: String = ok