列表模式匹配添加基于案例对象的过滤

问题描述

我有一个要迭代的男女居民列表。

如何在列表模式匹配中添加基于性别的过滤? (这样,countOldManFloor仅在居民性别为Male时返回1,结果countOldManFloor(inhabitantsFemale)会返回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))

Online code

我尝试了case inhabitant: Male :: inhabitants if inhabitant.age > olderThen => 1= inhabitants.filter() match {},但是没有用

解决方法

您可以在模式中匹配模式。在这种情况下,Male的{​​{1}}模式中的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,acc) case Nil => acc } countOldManFloor(inhabitantsBoth,olderThan) // 1 countOldManFloor(inhabitantsMale,olderThan) // 2 countOldManFloor(inhabitantsFemale,olderThan) // 0 设置了传递参数。在定义空间之外引用变量的方法是代码的味道。

,

我知道您需要的是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)
  }
,

您的方法无效,因为您未添加任何内容,只能返回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
}

Scastie

我认为您可以只使用count来执行此操作,而不必执行任何递归操作,

def countOldManFloor(inhabitants: List[Inhabitant]): Int = 
  inhabitants.count(inhabitant => inhabitant.age > olderThan && inhabitant.gender == Male)

Scastie

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...