是否可以将带通配符的密钥用于Scala Maps?例如形式(x,_)的元组?例如:
scala> val t1 = ("x","y")
scala> val t2 = ("y","x")
scala> val m = Map(t1 -> "foo", t2 -> "foo")
scala> m(("x","y"))
res5: String = foo
scala> m(("x",_))
<console>:11: error: missing parameter type for expanded function ((x$1) => scala.Tuple2("x", x$1))
m(("x",_))
^
如果有一种方法可以检索所有(composite_key,value)pares,其中只定义了复合键的某些部分,那将会很棒。在Scala中获得相同功能的其他方法是什么?
答案 0 :(得分:2)
如何使用收集
Map( 1 -> "1" -> "11", 2 -> "2" -> "22").collect { case (k@(1, _), v ) => k -> v }
答案 1 :(得分:1)
通常,您可以执行类似
的操作m.filter(m => (m._1 == "x"))
但在您的特定示例中,它仍将仅返回一个结果,因为Map每个键只有一个条目。如果你的密钥本身是复合的,那么它确实会更有意义:
scala> Map((1,2)->"a", (1,3)->"b", (3,4)->"c").filter(m => (m._1._1 == 1))
res0: scala.collection.immutable.Map[(Int, Int),String] = Map((1,2) -> a, (1,3) -> b)
答案 2 :(得分:1)
使用这样的理解:
for ( a @ ((k1,k2), v) <- m if k1 == "x" ) yield a
答案 3 :(得分:0)
想想Map
引擎盖下发生的事情。 Scala中的默认Map
是scala.collection.immutable.HashMap
,它根据哈希码存储内容。无论如何,("x", "y")
和("x", "y2")
是否都有相互关联的哈希码?不,他们不是,他们不是用这张地图实现通配符的有效方法。其他答案提供了解决方案,但这些解决方案将迭代整个Map
中的键/值对,这效率不高。
如果您希望自己想要执行此类操作,请使用TreeMap
。这并没有在内部使用哈希表,而是根据排序将元素放入树中。这类似于关系数据库使用B-Trees作为其索引的方式。您的通配符查询就像使用两列索引来过滤索引中的第一列。
以下是一个例子:
import scala.collection.immutable.TreeMap
val t1 = ("x","y")
val t2 = ("x","y2")
val t3 = ("y","x")
val m = TreeMap(t1 -> "foo1", t2 -> "foo2", t3 -> "foo3")
// "" is < than all other strings
// "x\u0000" is the next > string after "x"
val submap = m.from(("x", "")).to(("x\u0000", ""))
submap.values.foreach(println) // prints foo1, foo2