模式匹配-判断星座

12 阅读5分钟

一.变量声明中的模式匹配

现在有一个数组Array(1,2,3,4),定义三个变量,它们的值分别是数组中的第1,2,3个元素的值。

基础实现:

val arr = Array(1,2,3,4,5)
val x = arr(0)
val y = arr(1)
val z = arr(2)
println(x,y,z)

使用模式匹配的实现

val arr = Array(1,2,3,4)  
val Array(x,y,z,_*) = arr  
println(x,y,z)

其中: _*表示多个其他的元素值。

package matchcase

// match case 的用法

// (6)变量声明中的模式匹配
object matchcase06 {
  def main(args: Array[String]): Unit = {
    val arr = Array(1,2,3,4,5)

    // 定义三个变量,分别设置初始值为arr的前三个元素的值
    var a = arr(0)
    var b = arr(1)
    var c = arr(2)
    println("a = " + a + " b = " + b + " c = " + c)

    // 使用模式匹配,将arr的前三个元素分别赋值给a,b,c
    // _* 占位符,表示多的部分放在这儿
    val Array(x,y,z,_*) = arr
    println("x = " + x + " y = " + y + " z = " + z)
  }
}
package matchcase

/*
知识点:守卫
value match {
  case 模式 if 条件 => 执行的事情

 */
object matchcase07 {
  def main(args: Array[String]): Unit = {
    val a = 11
    
    a match {
      case x: Int if a > 10 => println("a是大于10的Int")
      case _ => println("a is not Int")
    }
  }
}

二.守卫语句的格式

守卫语句紧跟在case模式之后,通过if关键字引入,格式如下:

value match {
    case pattern if guardCondition => result
    // 其他case语句...
}
package matchcase

/*
知识点:守卫
value match {
  case 模式 if 条件 => 执行的事情

 */
object matchcase07 {
  def main(args: Array[String]): Unit = {
    val a = 11

    a match {
      case x: Int if a > 10 => println("a是大于10的Int")
      case _ => println("a is not Int")
    }
  }
}

其中,value是要进行匹配的值,pattern是匹配模式,guardCondition是守卫条件(一个布尔表达式),result是当该case分支匹配成功时返回的结果。 

具体如下:

从控制台读入一个数字a,使用(StdIn.readInt)

如果a>=0并且a<=3,打印[0-3]

如果 a>=4并且a<=8,打印[4-8]

否则:打印未匹配

【案例1】

在1-100内,如果数字>10并且是偶数,就输出:"是大于10的偶数",如果数字是>80并且是奇数,就输出:"是大于80的奇数"。

思路:在循环内部使用match case,并使用守卫语句。

for (i <- 1 to 100) {
  i match {
    case x if x > 10 && x % 2 == 0 => println(s"$i 是大于10的偶数")
    case x if x > 80 && x % 2 != 0 => println(s"$i 是大于80的奇数")
    case _ =>
  }
}

三.匹配for表达式

从Map中打印所有年龄为1971的创业者的信息。

val m1 = Map(  
  "马云 - 阿里巴巴" -> 1964,   "马化腾 - 腾讯" -> 1971,  
  "李彦宏 - 百度" -> 1968,   "雷军 - 小米" -> 1969,  
  "丁磊 - 网易" -> 1971,   "张一鸣 - 字节跳动" -> 1983,  
  "刘强东 - 京东" -> 1974,   "程维 - 滴滴" -> 1983,  
  "王兴 - 美团" -> 1979,   "周鸿祎 - 360" -> 1970,  
  "黄峥 - 拼多多" -> 1980,   "李想 - 理想汽车" -> 1981,  
  "何小鹏 - 小鹏汽车" -> 1977,   "贾跃亭 - 乐视" -> 1973,  
  "陈天桥 - 盛大网络" -> 1973,   "周源 - 知乎" -> 1980,  
  "王小川 - 搜狗" -> 1978  
)  
// 请补充代码,输出: 马化腾 - 腾讯, 丁磊 - 网易   
//  

方式1:使用 for + if守卫

for((key,year) <- m1 if year==1971){  
  println(key, year)  
}

方式2:使用模式匹配

for((key,1971) <- m1){  
  println(key, 1971)  
}

四.案例-判断星座

目标任务,编写一个函数,参数是月份和日期,返回值是当前的星座。

例如,getZodiac(3, 24) 返回白羊座 。

白羊座是3月21日 ~ 4月19日

先匹配月份,然后使用守卫功能,判断日期是否满足条件。

object Zodiac {

def getZodiac(month: Int, day: Int): String = {
    (month, day) match {
      case (1, d) if d >= 20 => "水瓶座"     
      case (12, d) if d >= 22 => "摩羯座"
      case (1, d) if d <= 19 => "摩羯座"
      case _ => "无效日期"
    }
  }
  def main(args: Array[String]): Unit = {
   println(getZodiac(3, 21)) // 输出: 白羊座
   println(getZodiac(12, 25)) // 输出: 摩羯座
 }

可对比介绍使用if else if 来实现的效果。

package matchcase

/*
    写一个函数,参数有两个,一个是月份,一个是日期。返回值是对应的星座
    1月20日到2月18日:水瓶座
 */
 
object matchcase08 {
  def getZodiac(month:Int, day:Int):String = {
    month match {
      case 1 if day >= 20 => "水瓶座"//月份是1,并且日期是>=20的
      case 2 if day <= 18 => "水瓶座"//月份是2,并且日期是<=18的
      case 2 if day >= 19 => "双鱼座"//月份是2,并且日期是>=19的
      case 3 if day <= 20 => "双鱼座"//月份是3,并且日期是<=20的
      case 3 if day >= 21 => "白羊座"//月份是3,并且日期是>=21的
      case 4 if day <= 19 => "白羊座"//月份是4,并且日期是<=19的
      case 4 if day >= 20 => "金牛座"//月份是4,并且日期是>=20的
      case 5 if day <= 20 => "金牛座"//月份是5,并且日期是<=20的
      case 5 if day >= 21 => "双子座"//月份是5,并且日期是>=21的
      case 6 if day <= 21 => "双子座"//月份是6,并且日期是<=21的
      case 6 if day >= 22 => "巨蟹座"//月份是6,并且日期是>=22的
      case 7 if day <= 22 => "巨蟹座"//月份是7,并且日期是<=22的
      case 7 if day >= 23 => "狮子座"//月份是7,并且日期是>=23的
      case 8 if day <= 22 => "狮子座"//月份是8,并且日期是<=22的
      case 8 if day >= 23 => "处女座"//月份是8,并且日期是>=23的
      case 9 if day <= 22 => "处女座"//月份是9,并且日期是<=22的
      case 9 if day >= 23 => "天秤座"//月份是9,并且日期是>=23的
      case 10 if day <= 23 => "天秤座"//月份是10,并且日期是<=23的
      case 10 if day >= 24 => "天蝎座"//月份是10,并且日期是>=24的
      case 11 if day <= 22 => "天蝎座"//月份是11,并且日期是<=22的
      case 11 if day >= 23 => "射手座"//月份是11,并且日期是>=23的
      case 12 if day <= 21 => "射手座"//月份是12,并且日期是<=21的
      case 12 if day >= 22 => "摩羯座"//月份是12,并且日期是>=22的
      case 1 if day <= 19 => "摩羯座"//月份是1,并且日期是<=19的
      case _ =>"未知"
    }
  }

  def main(args: Array[String]): Unit = {
    println(getZodiac(1,19))//水瓶座
    println(getZodiac(1,21))//水瓶座
  }
}