【问题标题】:Single key contains Multiple values in Map in scala单个键包含 Scala 中的 Map 中的多个值
【发布时间】:2017-04-23 09:03:21
【问题描述】:

我是 scala 的新手。我想为所有以下数据创建地图,其中包含 PINCODE 作为键,所有其他字段作为值。

<!DOCTYPE html>
<html>
<body>
<table border="1">
  <tr>
    <th>PINCODE</th>
    <th>Locality</th> 
    <th>PO_TYPE</th>
    <th>TALUK</th>
    <th>DISTRICT</th>
  </tr>
  <tr>
    <td>500001</td>
    <td>Hyderabad G.P.O.</td>
    <td>Branch Post Office</td>
    <td>Hyderabad</td>
    <td>HYDERABAD</td>
  </tr>
  <tr>
    <td>500001</td>
    <td>Gandhi Bhawan</td>
    <td>Branch Post Office</td>
    <td>Nampally</td>
    <td>HYDERABAD</td>
  </tr>
  <tr>
    <td>500001</td>
    <td>Hindi Bhawan</td>
    <td>Branch Post Office</td>
    <td>Nampally</td>
    <td>HYDERABAD</td>
  </tr>
  <tr>
    <td>500002</td>
    <td>Hyderabad Jubilee</td>
    <td>Branch Post Office</td>
    <td>HYDERABAD</td>
    <td>HYDERABAD</td>
  </tr>
  <tr>
    <td>500002</td>
    <td>Moghalpura Branch</td>
    <td>Post Office</td>
    <td>HYDERABAD</td>
    <td>HYDERABAD</td>
  </tr>
</table>

</body>
</html>

例如:(输出如下所示)

(500001, (Hyderabad G.P.O.,Branch Post Office,Hyderabad,HYDERABAD), (Gandhi Bhawan,邮局,南帕利,海得拉巴), (Hindi Bhawan,Branch Post Office,Nampally,HYDERABAD))

(500002 ,(Hyderabad Jubilee,Branch Post Office,HYDERABAD,HYDERABAD), (Moghalpura 分行,邮局,海得拉巴,海得拉巴))

提前致谢

【问题讨论】:

  • 为什么不把它设为Map[String, List[String]
  • 我是这样做的:var nodes = Map.empty[String , List[String]] nodes.+= ("123" -&gt;(List("abc","xyz","pqr","mno"))) 但是下次插入时nodes 被覆盖。

标签: html scala


【解决方案1】:

你想要MultiMap,例如:

  val mm = new mutable.HashMap[Int, mutable.Set[String]] with mutable.MultiMap[Int, String]
  mm.addBinding(500001, "a")
  mm.addBinding(500003, "b")
  mm.addBinding(500001, "c")
  val l = mm.getOrElse(500001, List())
  println(l)

对于List值类型,可以设置MultiMap值类型为:List[String],如:

  val mm = new mutable.HashMap[Int, mutable.Set[List[String]]] with mutable.MultiMap[Int, List[String]]
  mm.addBinding(500001, List("a", "b"))
  mm.addBinding(500003, List("b", "c"))
  mm.addBinding(500001, List("c", "D"))
  val l = mm.getOrElse(500001, Set())
  println(l)

输出:

  Set(List(e, f), List(a, b))

【讨论】:

  • 与此类似,但我想绑定具有索引的元素列表而不是单个字符串。像这样的东西:mm.addBinding(500001, List("a","b")) mm.addBinding(500003, List("b","c")) mm.addBinding(500001, List("c","D"))
  • @DarshanManek,我更新了我的答案,将值类型设置为List[String],希望对您有所帮助。
【解决方案2】:

实际上Map 应该是uniquely map 一个key 到一个value

因此,如果您想在同一个键上存储多个值(假设Strings),您可以将其设为Map[String, List[String]]

val map: Map[String, List[String]] = Map(
  "1" -> List("val_1_1", "val_1_2", "val_1_3"),
  "2" -> List("val_2_1", "val_2_2")
)

但是...至于您的情况,您似乎正在尝试使用不是Strings 但看起来更像地址描述的“值”。

在这种情况下,为什么不为 Address 创建一个类?

case class Address(
  locality: String,
  poType: String,
  taluk: String,
  district: String
)

// Now you can have you map

val map: Map[String, List[Address]] = Map(
  "500001" -> List(Address("Hyderabad G.P.O.", "Branch Post Office", "Hyderabad", "HYDERABAD"))
)

// define a function that we will use to add addresses without over-writing

def updateMapByAddingAddressWithPincode(
  map: Map[String, List[String]],
  pincode: String,
  address: Address
) = {
  val existingAddressListForPincode = map.getOrElse(pincode, default = List.empty[Address])
  map + (pincode -> address :: existingAddressListForPincode)
}

// now lets say, you want to add another address with same pincode "500001"

val newAddress = Address("Gandhi Bhawan", "Branch Post Office", "Nampally", "HYDERABAD")

val updatedMap = updateMapByAddingAddressWithPincode(
  map,
  "500001",
  newAddress
)

【讨论】:

  • 这是正确的,但如果我再次为“500001”添加任何值,那么它将覆盖第一个值。我希望所有值都出现在“500001”之前。
  • 是的...这就是updateMapByAddingAddressWithPincode。它将返回更新的地图而不会覆盖。您稍后会使用更新后的地图。
【解决方案3】:

基本上,您可以将Map[String, Set[String]] 与此处描述的特征MultiMap 混合在一起:

http://www.scala-lang.org/api/current/scala/collection/mutable/MultiMap.html

示例:

// first import all necessary types from package `collection.mutable`
import collection.mutable.{ HashMap, MultiMap, Set }

// to create a `MultiMap` the easiest way is to mixin it into a normal
// `Map` instance
val mm = new HashMap[Int, Set[String]] with MultiMap[Int, String]

// to add key-value pairs to a multimap it is important to use
// the method `addBinding` because standard methods like `+` will
// overwrite the complete key-value pair instead of adding the
// value to the existing key
mm.addBinding(1, "a")
mm.addBinding(2, "b")
mm.addBinding(1, "c")

【讨论】:

  • 与此类似,但我想绑定具有索引的元素列表而不是单个字符串。像这样的东西:mm.addBinding(500001, List("a","b")) mm.addBinding(500003, List("b","c")) mm.addBinding(500001, List("c","D"))
猜你喜欢
  • 2011-12-16
  • 1970-01-01
  • 1970-01-01
  • 2021-04-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-08-06
  • 1970-01-01
相关资源
最近更新 更多