如何从现有地图中导出scala中的新不可变地图

时间:2015-05-24 17:52:23

标签: scala maps

我认为这将是相对简单的。 所以我会解释一下:

我有一张地图如下:这是我在REPL中尝试的内容

scala> val entriesList = List(("tPolicyId" -> "MasterCard"), ("SSN" -> "0"), ("MasterCard" -> "3"));
entriesList: List[(String, String)] = List((tPolicyId,MasterCard), (US SSN,0), (MasterCard,3))

然后我将列表转换为Map,如下所示。

scala> val entriesMap = entriesList.toMap
entriesMap: scala.collection.immutable.Map[String,String] = Map(tPolicyId -> MasterCard,SSN -> 0, MasterCard -> 3)

到目前为止一切顺利。现在我想要实现的是迭代这个Map,有一个保护条件或谓词的方法:如果我用来迭代这个Map的函数遇到一个名为tPolicyMap的键,请返回或产生一个新的不可变量地图,newMap看起来像这样:

  ***newMap: scala.collection.immutable.Map[String,String] = Map(tPolicyId -> MasterCard)***

我认为这很容易,下面代表我到目前为止所有失败的尝试。

    scala> val tPolicyMap = for (entry <- entriesMap if entry.contains("tPolicyId")) yield  entry
<console>:10: error: value contains is not a member of (String, String)
       val tPolicyMap = for (entry <- entriesMap if entry.contains("tPolicyId")) yield  entry
                                                                   ^

scala> val tPolicyMap = for (entry <- entriesMap if ( entry.contains("tPolicyId"))) yield  entry
<console>:10: error: value contains is not a member of (String, String)
       val tPolicyMap = for (entry <- entriesMap if ( entry.contains("tPolicyId"))) yield  entry
                                                                     ^

scala> val tPolicyMap = for (entry <- entriesMap if ( entry.contains("tPolicyId"))) yield  (entry)
<console>:10: error: value contains is not a member of (String, String)
       val tPolicyMap = for (entry <- entriesMap if ( entry.contains("tPolicyId"))) yield  (entry)
                                                                     ^

scala> val tPolicyMap = for (entry <- entriesMap; if ( entry.contains("tPolicyId"))) yield  (entry)
<console>:10: error: value contains is not a member of (String, String)
       val tPolicyMap = for (entry <- entriesMap; if ( entry.contains("tPolicyId"))) yield  (entry)
                                                                      ^

scala> val tPolicyMap = for (entry <- entriesMap; if ( entry contains("tPolicyId"))) yield  (entry)
<console>:10: error: value contains is not a member of (String, String)
       val tPolicyMap = for (entry <- entriesMap; if ( entry contains("tPolicyId"))) yield  (entry)
                                                                      ^

scala> val tPolicyMap = for (entry <- entriesMap; if entry contains("tPolicyId"))) yield  entry
<console>:1: error: illegal start of simple expression
       val tPolicyMap = for (entry <- entriesMap; if entry contains("tPolicyId"))) yield  entry
                                                                                                   ^

scala> val tPolicyMap = for (entry <- entriesMap; if entry contains("tPolicyId")) yield  entry
<console>:10: error: value contains is not a member of (String, String)
       val tPolicyMap = for (entry <- entriesMap; if entry contains("tPolicyId")) yield  entry
                                                                    ^

scala> val tPolicyMap = for (entry <- entriesMap) yield  entry
tPolicyMap: scala.collection.immutable.Map[String,String] = Map(tPolicyId -> MasterCard/Diner's Club U
S Number, US SSN -> 0, MasterCard -> 3)

scala> val tPolicyEntry = entriesMap.contains("tPolicyId")
tPolicyEntry: Boolean = true

scala> val tPolicyEntry = if (entriesMap.contains("tPolicyId")) yield entriesMap
<console>:1: error: illegal start of simple expression
       val tPolicyEntry = if (entriesMap.contains("tPolicyId")) yield entriesMap
                                                                                  ^

scala> val tPolicyEntry = for(entry <- entriesMap; if entry == "tPolicyId" yield entry
<console>:1: error: ')' expected but 'yield' found.
       val tPolicyEntry = for(entry <- entriesMap; if entry == "tPolicyId" yield entry
                                                                                             ^

scala> val tPolicyEntry = for(entry <- entriesMap; if entry == "tPolicyId") yield entry
<console>:10: warning: comparing values of types (String, String) and String using `==' will always yield false
       val tPolicyEntry = for(entry <- entriesMap; if entry == "tPolicyId") yield entry
                                                                     ^
tPolicyEntry: scala.collection.immutable.Map[String,String] = Map()

scala> val tPolicyEntry = entriesMap.keys.foreach( (entry) => if(entriesMap.contains(entry)) yield entry
<console>:1: error: illegal start of simple expression
       val tPolicyEntry = entriesMap.keys.foreach( (entry) => if(entriesMap.contains(entry)) yield entry
                                                                                                      ^

scala> val tPolicyEntry = entriesMap.keys.foreach( (entry) => if(entriesMap.contains(entry)))) yield entry
<console>:1: error: illegal start of simple expression
       val tPolicyEntry = entriesMap.keys.foreach( (entry) => if(entriesMap.contains(entry)))) yield entry
                                                                                                     ^

scala> val tPolicyEntry = entriesMap.keys.foreach( (entry) => if(entriesMap.contains(entry)) yield entry)
<console>:1: error: illegal start of simple expression
       val tPolicyEntry = entriesMap.keys.foreach( (entry) => if(entriesMap.contains(entry)) yield entry)
                                                                                                      ^

scala> val tPolicyEntry = entriesMap.keys.foreach( (entry) => if(entriesMap.contains(entry)) yield entry))
<console>:1: error: illegal start of simple expression
       val tPolicyEntry = entriesMap.keys.foreach( (entry) => if(entriesMap.contains(entry)) yield entry))
                                                                                                      ^

scala> val tPolicyEntry = entriesMap.keys.foreach( (entry) => if(entriesMap.contains(entry) yield entry))
<console>:1: error: ')' expected but 'yield' found.
       val tPolicyEntry = entriesMap.keys.foreach( (entry) => if(entriesMap.contains(entry) yield entry))
                                                                                                     ^

scala> val tPolicyEntry = entriesMap.keys.foreach( (entry) => if(entriesMap.contains(entry) yield entry)
<console>:1: error: ')' expected but 'yield' found.
       val tPolicyEntry = entriesMap.keys.foreach( (entry) => if(entriesMap.contains(entry) yield entry)

正如您所看到的,我尝试过以各种方式使用filter,yield,foreach,for等失败。我仍然没有得到/

所以,我努力了,而且我可能会犯一些根本天真的错误。

如果有人可以帮我弄清楚如何获得我想要的地图,我会非常感谢学习经历

提前致谢

3 个答案:

答案 0 :(得分:2)

你正在考虑命令(迭代,比较,如果匹配然后这样做),而不是Scala不可变集合倾向于的更高级别:

// get looks up value from a map using the key (fast)
// will give you an Option[String] back - 
// Some(value) if the key exists, None if it doesn't
tpPolicyMap.get("tPolicyId").fold[Map[String, String]](
  // result for None - no "tPolicyId"-key in the source map
  Map.empty
)(value => 
  // found, create a new map with that entry
  Map("tPolicyId" -> value)
)

答案 1 :(得分:1)

就像

一样简单
 entriesMap.filter { case (k, _) => k == "tPolicyId" }
 //> res0: scala.collection.immutable.Map[String,String] = Map(tPolicyId -> MasterCard)

或者只是

 entriesMap filterKeys { _ == "tPolicyId"  }

答案 2 :(得分:0)

filter解决方案很好。您还可以执行collect,如果您打算在map

之后执行filter,这可能会很方便
entriesMap.collect{ case(k, v) if k == "tPolicyId" => (k, s"test${v}") } // example instead of plain (k, v)
// scala.collection.immutable.Map[String,String] = Map(tPolicyId -> testMasterCard)

与:

相同
(entriesMap filterKeys { _ == "tPolicyId"  }).map((kv) => (kv._1, s"test${kv._2}"))

// scala.collection.immutable.Map[String,String] = Map(tPolicyId -> testMasterCard)