Algorithm 如何根据模式匹配将一个贴图中的值替换为另一个贴图中的值?
我有一个有几个键值对的映射,我想要一种方法来遍历这些键值对,并尝试将这些键值与另一个映射的值相匹配。如果存在匹配项,则值将相互替换。换句话说,如果存在匹配,则第二个映射的值将替换第一个映射的值。如果没有匹配项,则不包括在结果中 我已经尝试过使用scala.map函数来计算逻辑,但是我对scala不太熟悉,不能完全理解它 例如,我有以下两个scala映射[String,String]:Algorithm 如何根据模式匹配将一个贴图中的值替换为另一个贴图中的值?,algorithm,scala,functional-programming,maps,match,Algorithm,Scala,Functional Programming,Maps,Match,我有一个有几个键值对的映射,我想要一种方法来遍历这些键值对,并尝试将这些键值与另一个映射的值相匹配。如果存在匹配项,则值将相互替换。换句话说,如果存在匹配,则第二个映射的值将替换第一个映射的值。如果没有匹配项,则不包括在结果中 我已经尝试过使用scala.map函数来计算逻辑,但是我对scala不太熟悉,不能完全理解它 例如,我有以下两个scala映射[String,String]: val lookupMap = Map("aaa" -> "apple", "bbb" -> "or
val lookupMap = Map("aaa" -> "apple", "bbb" -> "orange", "ccc" -> "banana")
val entriesMap = Map("foo" -> "ccc", "bar"-> "aaa", "baz" -> "zzz")
我想通过某种方式获得以下结果:
val result = Map("foo" -> "banana", "bar" -> "apple")
注意:“baz”未包括在内,因为它与查找映射中的任何内容都不匹配 A
for
理解可以解决这个问题
val result = for {
(k,ev) <- entriesMap
lv <- lookupMap.get(ev)
} yield (k,lv)
//result: Map[String,String] = Map(foo -> banana, bar -> apple)
val result=for{
(k,ev)苹果(apple)
让我们用更简单的步骤来解决问题
entriesMap
上的所有对,这些对的值在lookupMap
中不作为键存在lookupMap
上的值的值val result =
entriesMap
.filter { case (_, value) => lookupMap.contains(key = value) }
.map { case (key, value) => key -> lookupMap(value) }
但是,每次您想过滤
,然后映射
,都可以使用收集
(这将完成相同的工作,但只需一次迭代)。因此,您可以这样写:
val result = entriesMap.collect {
case (key, value) if lookupMap.contains(key = value) => key -> lookupMap(value)
}
现在,上述代码的一个“问题”是,它在映射上使用了不安全的apply
,如果它们的键不存在,就会抛出异常。
通常,应该使用get
方法,该方法将返回包装在选项上的值,如果键不存在,该选项将是None
在这种情况下,访问不是不安全的,因为我们正在检查之前是否存在密钥。无论如何,人们可以重新思考该计划:
lookupMap
上获取相关值,映射entriesMap
的值None
的对,然后展开Somes
val result =
entriesMap
.view // Only if you are in 2.13
.mapValues(value => lookupMap.get(key = value))
.collect { case (key, Some(value)) => key -> value }
.toMap // This is necessary because mapValues returns a view, which is a lazy collection.
// Other option would have been to use just map instead of mapValues.
最后,可以使用来理解,而不是直接使用高阶函数因此,该代码(与jwvh的答案几乎相同):
val结果=
为了{
(关键、价值)@LuisMiguelMejíaSuárez您给出的第一个选项正是我想要的!您能用简单的英语解释一下您的想法吗?我正在尝试学习scala语法和函数式思维方式。另外,这个选项和第二个选项有什么区别?我注意到它返回了一个视图,但我不熟悉视图。这是代码吗afe?我这样问是因为下面的线程中有人提出了一个我没有考虑太多的问题。如果一个键不存在怎么办?这在任何情况下都会引发异常吗?或者它本身与一些或没有关系?@jjaguirre394;是的,它是安全的。你可以自己看到它会逐步通过entriesMap
,包括如果值存在(即某些(“…”)
),它将在查找映射上调用.get()
,该映射将返回一个选项[String]
然后它被展开并分配给变量lv
。如果不是这样,那么理解的就直接进入迭代。需求发生了变化,看起来现在我必须查找类型Map[String,Map[String,String]]。我提出的函数看起来像val res=for{(k,ev)@jjaguirre394;您的评论中没有足够的信息来提供一个自信的答案。您可能想提交一个包含足够细节的新问题,包括示例输入和预期输出。在此之前,我只能说lookupMap.get(k).get(ev)
不起作用,因为lookupMap.get(k)
返回一个选项
,而选项
类型没有.get(key)
方法。
val result =
for {
(key, value) <- entriesMap // For each key-value pair in entriesMap...
newValue <- lookupMap.get(key = value) // And for each newValue associated with each original value...
} yield key -> newValue // Yield the key-newValue pair.