我有一个看起来像这样的scala multimap
Key: fish value: Set:(salmon,batam fish, shark)
Key: winged animals value: Set:(chicken, ducks)
我有一个字符串文本,如下所示:
val string = "the market had sold salmon and chicken"
由于这根绳子里有鲑鱼和鸡肉,我需要把钥匙放回鱼和有翅膀的动物身上。
有没有办法迭代值集并在匹配时返回密钥?我可以循环键值对,但我只能获得如上所示的多图,而不是单个值。
由于
答案 0 :(得分:0)
val index: Map[String, Set[String]] = Map(
"Fish" -> Set("salmon", "batam", "shark"),
"Winged Animals" -> Set("chicken", "ducks"),
"Other" -> Set("cow", "pig")
)
def typesInString(search: String): Set[String] = index.filter {
case (t, vals) =>
vals.exists(search.contains)
}.keys.toSet
typesInString("the market had sold salmon and chicken")
// Set(Fish, Winged Animals)
答案 1 :(得分:0)
一种方法是从MultiMap创建反向Map以进行值键查找,如下所示:
import collection.mutable.{ Set, HashMap, MultiMap }
val text = "the market had sold salmon and chicken"
val mm = new HashMap[String, Set[String]] with MultiMap[String, String]
mm.addBinding("fish", "salmon")
mm.addBinding("fish", "batam fish")
mm.addBinding("fish", "shark")
mm.addBinding("winged animals", "chicken")
mm.addBinding("winged animals", "ducks")
val reverseList = for {
mList <- mm.toList
mValue <- mList._2
}
yield (mValue, mList._1)
// Use groupBy instead of toMap (*)
val reverseMap = reverseList.groupBy(_._1).mapValues(_.map(_._2))
// reverseMap: scala.collection.immutable.Map[String,List[String]] = Map(
// salmon -> List(fish), ducks -> List(winged animals), chicken -> List(winged animals),
// shark -> List(fish), batam fish -> List(fish)
// )
text.split("\\s+").collect{
case x if reverseMap.contains(x) => reverseMap(x)
}
// res1: Array[List[String]] = Array(List(fish), List(winged animals))
(*)请注意,groupBy
代替toMap
会应用于reverseList
,以允许属于多个群组的动物;这也是为什么结果是嵌套的集合(例如蝙蝠可能属于List(哺乳动物,有翼动物))。
答案 2 :(得分:0)
如果没有循环键值对,只使用自己的MultiMap
方法,我们仍然需要遍历键:
val items: MultiMap[String, String] = ...
val string = "the market had sold salmon and chicken"
val matched = items.keys.filter(key => items.entryExists(key, string.contains(_)))
println(matched)
// Set(winged animals, fish)