在scala中清除地图

时间:2017-09-08 10:18:41

标签: scala hadoop dictionary apache-spark

问题陈述:

当我尝试清除Map列时,处理程序Map的列部分也会被清除。有什么方法可以避免这种情况吗?

def getTransformations(configuration: NodeSeq) {
var id: Int = 0
var methodCall: String = ""
val completeTransformation = Map[Int, Map[String, Map[String, String]]]()
val transformationsMap = Map[Int, Map[String, Map[String, String]]]()
val handlers = Map[String, Map[String, String]]()
val columns = Map[String, String]()

for (transformations <- configuration \\ "transformations") {
  for (transformation <- transformations \\ "transformation") {
    id += 1
    for (handler <- transformation \\ "handler") {
       for (input <- handler \\ "input") {
           columns.+=(((input \\ "@name").mkString) -> input.text)
      }
      handlers(handler.attribute("type").mkString) = columns
      columns.clear()
    }
    transformationsMap(id) = handlers
    handlers.clear()
   }
 }
transformationsMap
}

实施例: As seen in the image the handlers Map is build using the columns Map

When the columns.clear is executed, its value in handlers Map is also cleared

2 个答案:

答案 0 :(得分:0)

handlers(handler.attribute("type").mkString) = columns
columns.clear()

您只是将参考columns设置为handlers而不是值。 当您清除columns时,您将从columns引用的内存中移除值,并且handlers中您引用columns的值也会反映更改。 Tats all。要避免此问题,请创建columns的新副本并将其分配给handler

 handlers(handler.attribute("type").mkString) =  collection.mutable.Map[String,String]() ++= columns

它取决于你,在创建新副本时你想要可变或不可变的地图。

答案 1 :(得分:0)

FWIW,&#34; scala&#34;写下你想要做的事情的方式是这样的:

 val transformationsMap = (configuration \\ "transformations")
    .flatMap(_ \\ "transformation") 
    .zipWithIndex
    .map { case (trf, idx) => (idx+1) -> trf }
    .toMap
    .mapValues(_ \\ "handler)
    .mapValues {
      _.map { h => h.attribute("type").mkString -> (h \\ "input") }
       .toMap
       .mapValues { 
         _.map { in => (in \\ "@name".mkString) -> in.text }
           .toMap
       }                 
    }