Scala集合,单键多个值 [英] Scala collections, single key multiple values

查看:113
本文介绍了Scala集合,单键多个值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个父键的列表,每个键可能有零个或多个关联值。我不知道使用哪个集合。



我使用 Map [Int,List [String]] / p>

我声明映射为

  var nodes = new HashMap [ Int,List [String]] 

然后我有两个方法来处理添加新的元素。第一个是添加新的键 addNode ,第二个是添加新值 addValue 。最初,密钥将不具有与其相关联的任何值。

  def addNode(key:Int)= nodes + = >)

def addValue(key:Int,value:String)=?



我不知道如何实现 addValues



更新:



响应@ oxbow-lakes回答,这是我收到的错误。请注意,键不必具有与其关联的值。

  scala> var nodes = Map.empty [Int,List [String]] 
nodes:scala.collection.immutable.Map [Int,List [String]] = Map()

scala> nodes + =(1-> null)

scala>节点+ =(1 - >(one::(nodes get 1 getOrElse Nil)))
java.lang.NullPointerException
at。< init>(< console&
at。< clinit>(< console>)
at。< init>(< console>:11)
at。< clinit>(< console>
at $ print(< console>)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native方法)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at scala.tools.nsc.interpreter .Main $ ReadEvalPrint.call(IMain.scala:704)
at scala.tools.nsc.interpreter.IMain $ Request $$ anonfun $ 14.apply(IMain.scala:920)
在scala.tools .nsc.interpreter.Line $$ anonfun $ 1.apply $ mcV $ sp(Line.scala:43)
at scala.tools.nsc.io.package $$ anon $ 2.run(package.scala:25)
at java.lang.Thread.run(Thread.java:680)



更新2 :



上面代码的问题是 nodes + =(1-> null)应该与 Nil 相关联。以下是工作代码。

  scala> var nodes = Map.empty [Int,List [String]] 
nodes:scala.collection.immutable.Map [Int,List [String]] = Map()

scala> nodes + =(1-> Nil)

scala>节点+ =(1 - >(one::(nodes get 1 getOrElse Nil)))

scala>节点
res27:scala.collection.immutable.Map [Int,List [String]] = Map(1 - > List(一))


解决方案

使用MultiMap



您可能想使用 MultiMap ,它是与 Map [K,Set [V]] 同构的可变集合。使用方式如下:

  import collection.mutable 
val mm = new mutable.HashMap [Int,mutable.Set [ String]] with mutable.MultiMap [Int,String]

然后添加节点:

  mm addBinding(key,value)



没有MultiMap



另一种方法是坚持使用不可变的值。假设您想避免使用镜头(请参阅),您可以按如下所示添加节点:

  nodes + =(key  - >(value ::(nodes get key getOrElse Nil)))


b $ b

这里它是工作(回应你的评论):

  scala> var nodes = Map.empty [Int,List [String]] 
nodes:scala.collection.immutable.Map [Int,List [String]] = Map()

scala> def addNode(key:Int,value:String)=
|节点+ =(key - >(value ::(nodes get key getOrElse Nil)))
addNode:(key:Int,value:String)单位

scala> addNode(1,Hi)

scala> addNode(1,Bye)

scala>节点
res2:scala.collection.immutable.Map [Int,List [String]] = Map(1 - > List(Bye,Hi))



使用Scalaz



使用scalaz库,你可以意识到这只是使用 Empty 模式:

 节点+ =(键 - > node get key)))

或者你可以利用地图 monoid

  nodes = nodes |映射(键 - >列表(值))


I have a list of parent keys, each of which could possibly have zero or more associated values. I am not sure which collection to use.

I am using Map[Int,List[String]]

I am declaring the Map as

var nodes = new HashMap[Int, List[String]]

Then I have two methods to handle adding new elements. The first is to add new keys addNode and the second is to add new values addValue. Initially, the key will not have any values associated with it. Later on, during execution, new values will be associated.

def addNode(key: Int) = nodes += (key -> "")

def addValue(key: Int, value: String) = ???

I am not sure how to implement addValues

Update:

In response to @oxbow-lakes answer, This is the error I am receiving. Please note that keys need not have values associated with them.

scala> var nodes = Map.empty[Int, List[String]]
nodes: scala.collection.immutable.Map[Int,List[String]] = Map()

scala> nodes += (1->null)

scala> nodes += (1 -> ("one" :: (nodes get 1 getOrElse Nil)))
java.lang.NullPointerException
    at .<init>(<console>:9)
    at .<clinit>(<console>)
    at .<init>(<console>:11)
    at .<clinit>(<console>)
    at $print(<console>)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at scala.tools.nsc.interpreter.IMain$ReadEvalPrint.call(IMain.scala:704)
    at scala.tools.nsc.interpreter.IMain$Request$$anonfun$14.apply(IMain.scala:920)
    at scala.tools.nsc.interpreter.Line$$anonfun$1.apply$mcV$sp(Line.scala:43)
    at scala.tools.nsc.io.package$$anon$2.run(package.scala:25)
    at java.lang.Thread.run(Thread.java:680)

Update 2:

The problem with the code above is the line nodes += (1->null) the key should be associated with Nil instead. Below is the working code.

scala> var nodes = Map.empty[Int, List[String]]
nodes: scala.collection.immutable.Map[Int,List[String]] = Map()

scala> nodes += (1->Nil)

scala> nodes += (1 -> ("one" :: (nodes get 1 getOrElse Nil)))

scala> nodes
res27: scala.collection.immutable.Map[Int,List[String]] = Map(1 -> List(one))

解决方案

Using MultiMap

You possibly want to use MultiMap, which is a mutable collection isomorphic to Map[K, Set[V]]. Use as follows:

import collection.mutable
val mm = new mutable.HashMap[Int, mutable.Set[String]] with mutable.MultiMap[Int, String]

Then you add your nodes:

mm addBinding (key, value)

Without MultiMap

The alternative is to stick with immutable values. Assuming you want to avoid using lenses (see scalaz), you can add nodes as follows:

nodes += (key -> (value :: (nodes get key getOrElse Nil)))

Here it is working (in response to your comment):

scala> var nodes = Map.empty[Int, List[String]]
nodes: scala.collection.immutable.Map[Int,List[String]] = Map()

scala> def addNode(key: Int, value: String) =
     | nodes += (key -> (value :: (nodes get key getOrElse Nil)))
addNode: (key: Int, value: String)Unit

scala> addNode(1, "Hi")

scala> addNode(1, "Bye")

scala> nodes
res2: scala.collection.immutable.Map[Int,List[String]] = Map(1 -> List(Bye, Hi))

Using Scalaz

Using the scalaz library, you can realize that this is simply using the Empty pattern:

nodes += (key -> (value :: ~(nodes get key)))

Or you could take advantage of the fact that Map is a monoid:

nodes = nodes |+| Map(key -> List(value))

这篇关于Scala集合,单键多个值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆