列表模式匹配添加基于案例对象的过滤
List pattern matching add filtering based on case object
我有一个要迭代的男性和女性居民列表。
如何在列表模式匹配中添加基于性别的过滤? (只有当居民性别为 Male
时 countOldManFloor
才会 return 1,因此 countOldManFloor(inhabitantsFemale)
会 return 0)
import scala.annotation.tailrec
trait Gender
case object Female extends Gender
case object Male extends Gender
case class Inhabitant(age: Int= 50, gender: Gender)
val olderThen = 30
val inhabitantsBoth: List[Inhabitant] = List(Inhabitant(gender=Male), Inhabitant(gender=Female))
val inhabitantsFemale: List[Inhabitant] = List(Inhabitant(gender=Female), Inhabitant(gender=Female))
val inhabitantsMale: List[Inhabitant] = List(Inhabitant(gender=Male), Inhabitant(gender=Male))
@tailrec
def countOldManFloor(inhabitants: List[Inhabitant]): Int = inhabitants match {
case inhabitant :: inhabitants if inhabitant.age > olderThen => 1
case inhabitant :: inhabitants => countOldManFloor(inhabitants)
case Nil => 0
}
println(countOldManFloor(inhabitantsBoth))
println(countOldManFloor(inhabitantsMale))
println(countOldManFloor(inhabitantsFemale))
我试过 case inhabitant: Male :: inhabitants if inhabitant.age > olderThen => 1
和 = inhabitants.filter() match {}
但没用
我了解到您需要的是 30 岁以上男性的计数器,因此我添加了性别条件检查。
def countOldManFloor(inhabitants: List[Inhabitant]): Int = {
def checkGender(inhabitant: Gender): Boolean = inhabitant match {
case Male => true
case _ => false
}
@tailrec
def loop(lst: List[Inhabitant], cont: Int): Int = {
lst match {
case Nil => cont
case (h :: tail) if h.age > olderThen && checkGender(h.gender) => loop(tail, cont + 1)
case _ => loop(lst.tail, cont)
}
}
loop(inhabitants, 0)
}
您可以在模式中匹配模式。在这种情况下,Male
模式,在 Inhabitant()
模式中,在 List
的 ::
模式中。
@tailrec
def countOldManFloor(inhabitants : List[Inhabitant]
,ageLimit : Int
,acc : Int = 0): Int = inhabitants match {
case Inhabitant(age,Male) :: tl if age > ageLimit =>
countOldManFloor(tl, ageLimit, acc + 1)
case _ :: tl => countOldManFloor(tl, ageLimit, acc)
case Nil => acc
}
countOldManFloor(inhabitantsBoth, olderThan) // 1
countOldManFloor(inhabitantsMale, olderThan) // 2
countOldManFloor(inhabitantsFemale, olderThan) // 0
请注意,我将 olderThan
设为传递参数。在定义之外引用变量的方法 space 是一种代码味道。
您的方法无效,因为您没有添加任何东西,只能返回 1 和 0。如果您不关心尾递归,这可能有效:
def countOldManFloor(inhabitants: List[Inhabitant]): Int = inhabitants match {
case Inhabitant(age, Male) :: inhabitants if age > olderThan => countOldManFloor(inhabitants) + 1
case inhabitant :: inhabitants => countOldManFloor(inhabitants)
case Nil => 0
}
我认为你可以只用 count
而不是任何递归来做到这一点:
def countOldManFloor(inhabitants: List[Inhabitant]): Int =
inhabitants.count(inhabitant => inhabitant.age > olderThan && inhabitant.gender == Male)
我有一个要迭代的男性和女性居民列表。
如何在列表模式匹配中添加基于性别的过滤? (只有当居民性别为 Male
时 countOldManFloor
才会 return 1,因此 countOldManFloor(inhabitantsFemale)
会 return 0)
import scala.annotation.tailrec
trait Gender
case object Female extends Gender
case object Male extends Gender
case class Inhabitant(age: Int= 50, gender: Gender)
val olderThen = 30
val inhabitantsBoth: List[Inhabitant] = List(Inhabitant(gender=Male), Inhabitant(gender=Female))
val inhabitantsFemale: List[Inhabitant] = List(Inhabitant(gender=Female), Inhabitant(gender=Female))
val inhabitantsMale: List[Inhabitant] = List(Inhabitant(gender=Male), Inhabitant(gender=Male))
@tailrec
def countOldManFloor(inhabitants: List[Inhabitant]): Int = inhabitants match {
case inhabitant :: inhabitants if inhabitant.age > olderThen => 1
case inhabitant :: inhabitants => countOldManFloor(inhabitants)
case Nil => 0
}
println(countOldManFloor(inhabitantsBoth))
println(countOldManFloor(inhabitantsMale))
println(countOldManFloor(inhabitantsFemale))
我试过 case inhabitant: Male :: inhabitants if inhabitant.age > olderThen => 1
和 = inhabitants.filter() match {}
但没用
我了解到您需要的是 30 岁以上男性的计数器,因此我添加了性别条件检查。
def countOldManFloor(inhabitants: List[Inhabitant]): Int = {
def checkGender(inhabitant: Gender): Boolean = inhabitant match {
case Male => true
case _ => false
}
@tailrec
def loop(lst: List[Inhabitant], cont: Int): Int = {
lst match {
case Nil => cont
case (h :: tail) if h.age > olderThen && checkGender(h.gender) => loop(tail, cont + 1)
case _ => loop(lst.tail, cont)
}
}
loop(inhabitants, 0)
}
您可以在模式中匹配模式。在这种情况下,Male
模式,在 Inhabitant()
模式中,在 List
的 ::
模式中。
@tailrec
def countOldManFloor(inhabitants : List[Inhabitant]
,ageLimit : Int
,acc : Int = 0): Int = inhabitants match {
case Inhabitant(age,Male) :: tl if age > ageLimit =>
countOldManFloor(tl, ageLimit, acc + 1)
case _ :: tl => countOldManFloor(tl, ageLimit, acc)
case Nil => acc
}
countOldManFloor(inhabitantsBoth, olderThan) // 1
countOldManFloor(inhabitantsMale, olderThan) // 2
countOldManFloor(inhabitantsFemale, olderThan) // 0
请注意,我将 olderThan
设为传递参数。在定义之外引用变量的方法 space 是一种代码味道。
您的方法无效,因为您没有添加任何东西,只能返回 1 和 0。如果您不关心尾递归,这可能有效:
def countOldManFloor(inhabitants: List[Inhabitant]): Int = inhabitants match {
case Inhabitant(age, Male) :: inhabitants if age > olderThan => countOldManFloor(inhabitants) + 1
case inhabitant :: inhabitants => countOldManFloor(inhabitants)
case Nil => 0
}
我认为你可以只用 count
而不是任何递归来做到这一点:
def countOldManFloor(inhabitants: List[Inhabitant]): Int =
inhabitants.count(inhabitant => inhabitant.age > olderThan && inhabitant.gender == Male)