scala> userMap.values.exists{ case User(_, surName1, _, _ ) => true }
res1: Boolean = true
但是,如果您要进行更改,请不要检查是否为真,然后去做。这是必要的非 scala 思维方式。这是一种温和的邪恶方式:
var changed = false
userMap map { x => x match {
case (n, User(i, f, "surName1", p)) => {
changed = true
(n, User(i, f, "Appleyard", p))
}
case _ => x
}
}
这样做是返回 userMap 的副本(因为您的 userMap 可能是不可变的,除非您指定了可变映射),任何“surName1”用户都更改为“Appleyards”。如果找到任何匹配的用户,“已更改”将设置为 true 作为副作用。我称之为轻度邪恶,因为它使用副作用。请注意,有一种非常简单的方法可以避免副作用...
scala> newMap = userMap map { x => x match {
case (n, User(i, f, "surName1", p)) => {
(n, User(i, f, "Appleyard", p))
}
case _ => x
}
}
scala> newMap == userMap
res2: Boolean = false
现在这里有更正式的东西
def surnameA2B(oldName: String, newName: String, m: Map[Int,User]): (Int, Map[Int,User]) = {
val changed = m collect {
case (n, User(i, f, s, p)) if s == oldName =>
(n, User(i, f, newName, p))
}
(changed.size, m ++ changed)
}
surnameA2B("surName1", "Appleyard", userMap)
res1: (Int, Map[Int,User]) = (1,Map(1 -> User(1,firstName1,Appleyard,1111), 2 -> User(2,firstName2,surName2,2222), 3 -> User(3,firstName3,surName3,3333)))
给定要匹配的名称、替换名称和用户映射,它会返回已更改用户的计数和已更改的新用户映射。0 表示没有变化,因此您可以通过测试计数是否为 0 来得出布尔值。
检查一个条件,如果它是真的就采取行动,然后根据动作设置一个条件是一种非常必要的、非 Scala 的做事方式。事实上,很少需要检查一个条件是否为真,当您可以链接函数时,如果 B 完成,A 将自然发生(如果需要,对于 B 的每个相关迭代。Scala 使尝试这种方法变得容易,并且它会产生更清晰的代码。