07.Swift条件和循环语句

/*控制转移语句:
 continue: 本次循环完成了,开始下一次循环
 break:结束循环,跳到循环体结束的大括号后的第一行代码
 fallthrough:贯穿,会穿透当前,执行下一步
 return
 throw
 
 */
//=================================if、guard-else、for-in 语句=================================
let dataArr = [15,51,67,89,32]
var num = 0
for score in dataArr {//遍历数组,大于50,num加3,否则加1
    if score > 50 {
        num += 3
    }else{
        num += 1
    }
}
print("num的值为:\(num)")

//可选值:在类型后加一个?
//可以使用if 和 let来处理值缺失的情况,这个值可以用可选值来代替(可选值是一个具体的值或者nil,如果是nil表示的是值缺失,在类型后面加一个?来表示这个变量的值是可选的)
var optionStr:String? = "Hello"
print(optionStr == nil)//输出的是判断结果

var optionName:String? = nil//"张三"
var greeting = "World!"
if let name = optionName{//optionName 不为nil,会把值赋值给name,这样在代码块中就可以用了
    greeting = "Hello,\(name)"
}else{
    greeting = "HelloKitty"//进入到此name相当于没有定义
}

//默认值 用 ?? 表示
let nickName:String? = "小四儿"// nil
let fullName:String? = "李四"
let informalGreeting = "Hi \(String(describing: nickName ?? fullName))"//如果nickName为nil就用fullName

//遍历数组和字典
let arrDic = ["x": [2, 3, 5, 7, 11, 13],
              "y": [1, 1, 2, 3, 5, 8],
              "z": [1, 4, 9, 16, 25],
             ]
var max = 0
for (_,value) in arrDic {//遍历字典,前一个key用不到可以用_代替
    for num in value { //遍历字典的每个value数组
        if num > max {//如果value数组中的值大于max
            max = num//就把这个值赋值给max
        }
    }
}
print("字典中的最大值为:\(max)")

//guard-else 提前退出:guard不成立则走else ,成立则走guard结束大括号后面的代码
func testGuardGreet(person:[String: String]){
    guard let name = person["name"] else { //获取字典中的name
        print("guard语句不成立,此处也没有name这个变量")
        return
    }
    print("字典中有name:\(name)")
    guard let location = person["location"] else {
        print("字典中没有location这个值,此处也无此变量定义")
        return
    }
    print("字典中既有name也有location:\(location)")
}
testGuardGreet(person: ["name":"张三"])
testGuardGreet(person: ["name" : "李四","location":"北京"])

//检查API是否可用:
if #available(iOS 11, *){
    print("使用#available检查 一些API是否可用")
}

//=================================while、repeat-While语句=================================
var n = 2
while n<100 {
    n = n*2
}
print("while循环结束后的n的值:\(n)")

var mm = 1
repeat {
    mm = mm*2
}while mm<50
print("repeat-while循环中,结束条件后置:\(mm)")

var total = 0
for i in 0..<4 {
    total += i
}
print("循环的范围:\(total)")//使用..< 创建的范围不包含上界,如果想包含的话需要使用...

var total2 = 0
for j in 0...4{
    total2 += j
}
print("包括上界的循环范围:\(total2)")

//间隔遍历:每隔x遍历一次
for index in stride(from: 0, to: 60, by: 3) { //从0-60 每隔3 遍历一次
    print("半开区间-间隔遍历:\(index)") // 0、3、6、9、……57 (to不包括60)
}
for index in stride(from: 1, through: 10, by: 2) {//遍历1-10,每隔2遍历一次
    print("闭区间- 间隔遍历:\(index)")//1-10: 1、3、5、7、9; 0-10:0、2、4、6、8、10
}

/*蛇与梯子(见图snakesAndLadders_2x的示例:)
    游戏规则:如果在梯子底部,会直接爬到梯子顶部;如果在蛇头,会直接滑到蛇尾;从0开始,每次掷骰子来决定走几步
 */
let geNum = 25;//表格的总数量
var geArr = [Int](repeating: 0, count: geNum+1);//初始化每个格子的规则 都为0
geArr[3] = 8 //如果到了格子3,就加8,直接爬到格子11
geArr[6] = 11 //如果到了格子6,就加11,直接爬到格子17
geArr[9] = 9 //如果到了格子9,就加9,直接爬到格子18
geArr[10] = 2 //如果到了格子10,就加2,直接爬到格子12
geArr[14] = -10 //如果到了格子14,就减10,会直接滑到格子4
geArr[19] = -11 //如果到了格子19,就减11,直接滑到格子8
geArr[22] = -2 //如果到了格子22,就减2,直接滑到格子20
geArr[24] = -8 //如果到了格子24,就减8,直接滑到格子16

var currentGe = 0 //记录当前所在的格子(从0开始)
var diceNum = 0 //记录每次掷骰子的数(模拟按每次+1:1、2、3、4、5、6、1)
while currentGe < geNum { //只要当前所在的格子小于25,游戏就没有结束
    diceNum += 1//每次掷骰子数都在上次掷骰子的数的基础上+1
    if diceNum == 7 { //如果超过了6,就回到1,继续
        diceNum = 1
    }
    currentGe += diceNum //每次都往前移动掷出来的骰子数个格子

    if currentGe < geArr.count {//如果游戏没有结束
        currentGe += geArr[currentGe]// 额外再满足一下游戏的规则(上升或下滑)
        print("当前格子数是:\(currentGe)")
    }
}
print("游戏结束")

//=================================switch语句=================================
//switch语句:任意类型都可以,匹配上之后会退出switch,所以不需要再每个语句后面加上break;但是每个case分支后面都必须包含至少一条语句,否则会报错,如果语句为空,就把这个case条件给去掉;或者直接写break跳出switch
let tag = "red"
switch tag {
case "red":
    print("颜色为red")
    print("选对了")
case "green","GREEN": //一个case语句后面可以同时匹配多个,用逗号分隔
    print("颜色为--绿色")
case let x where x.hasSuffix("d")://如果前面都没有匹配上,而且tag的后缀是“d”,就会走进这个匹配,并将tag的值赋值给常量x在代码块中使用
    print("特色的switch-case语句:\(x)")//匹配上x的值就是tag的值
default:
    print("没有符合的")
}
//case语句也可以是区间匹配,例如: case 1..<3: 这种
//switch匹配元组
let somePoint = (1,1)
switch somePoint {//如果条件满足很多个case,只会执行第一个满足的case,后面的都不会执行
case (0,0):
    print("0,0")
case (_, 0):
    print("在x轴上")
case (0,_):
    print("在y轴上")
case (-2...2,-2...2):
    print("在一个封闭的区间中")
default:
    print("没找到")
}

//switch 允许判断条件为常量或者变量---值绑定
let anotherPoint = (2,0)
switch anotherPoint {
case (let x,0)://匹配一个y为0的点,并将这个点的横坐标传给x
    print("匹配在x轴上的一个值:\(x)")
case (0,let y),(let y,0)://匹配一个x为0的点,并将这个点的纵坐标传给y;后面是一个复合匹配,let定义的变量需要一致才能在下面使用
    print("匹配在y轴上的一个值:\(y)")
case let(x, y)://匹配任意一个x,y的点;由于肯定会满足这一条件,所以后面不需要再写默认的default分支了
    print("匹配任意一个点的xy坐标:\(x,y)")
}

//switch 判断条件可以用where语句来增加额外的条件
let yetPoint = (1,-1)
switch yetPoint {
case let (x,y) where x == y://x,y都是占位符,需要满足where后面的条件才可以执行这个case
    print("\(x,y)在 x==y 这个对角线上")
case let (x,y) where x == -y:
    print("\(x,y)在 x==-y这个对角线上")
case let (x,y):
    print("\(x,y)这个点不在上面那两条对角线上")
}

//=================================控制转移语句:=================================
//continue: 本次循环完成了,开始下一次循环
let puzzleInput = "great minds think alike"
var puzzleOutput = ""
for character in puzzleInput {//遍历字符串
    switch character {
    case "a","e","i","o","u"," "://跳过元音字符和空格
        continue
    default:
        puzzleOutput.append(character)//把其他的字符拼接到一块
    }
}
print("拼接后的字符串为:\(puzzleOutput)")

//break:结束循环,跳到循环体结束的大括号后的第一行代码
let numberSymbol:Character = "三"
var possibleIntValue: Int?
switch numberSymbol {
case "1","一","壹":
    possibleIntValue = 1
case "二","2","贰":
    possibleIntValue = 2
case "叁","3","三":
    possibleIntValue = 3
default:
    break
}
if let posNum = possibleIntValue {
    print("匹配的结果为:\(posNum)")
}else{
    print("没有匹配上")
}

//fallthrough:贯穿,会穿透当前,执行下一步
let desNum = 5
var desStr = "数据\(desNum),"
switch desNum {
case 2,3,4,5,6:
    desStr += "匹配上了"
    fallthrough
case 0,1,7,8,9:
    desStr += ",case穿透了"
default:
    desStr += ",default穿透了"
}
print("穿透结果:\(desStr)")//带fallthrough语句,会直接穿透到下一步,而无视case的条件

//带标签的语句:为了在前提循环中很好的区分是哪个循环的break和continue,可以使用一个标签来标记一个循环体或者条件语句
//蛇与梯子的升级版:刚好落到最后一个格子才算胜利
let geNum2 = 25;//表格的总数量
var geArr2 = [Int](repeating: 0, count: geNum2+1);//初始化每个格子的规则 都为0
geArr2[3] = 8 //如果到了格子3,就加8,直接爬到格子11
geArr2[6] = 11 //如果到了格子6,就加11,直接爬到格子17
geArr2[9] = 9 //如果到了格子9,就加9,直接爬到格子18
geArr2[10] = 2 //如果到了格子10,就加2,直接爬到格子12
geArr2[14] = -10 //如果到了格子14,就减10,会直接滑到格子4
geArr2[19] = -11 //如果到了格子19,就减11,直接滑到格子8
geArr2[22] = -2 //如果到了格子22,就减2,直接滑到格子20
geArr2[24] = -8 //如果到了格子24,就减8,直接滑到格子16

var currentGe2 = 0 //记录当前所在的格子(从0开始)
var diceNum2 = 0 //记录每次掷骰子的数(模拟按每次+1:1、2、3、4、5、6、1)
gameLoop: while currentGe2 != geNum2 { //该循环的标签为gameLoop,只要当前格子不在终点格子上就循环
    diceNum2 += 1//每次掷骰子数都在上次掷骰子的数的基础上+1
    if diceNum2 == 7 { //如果超过了6,就回到1,继续
        diceNum2 = 1
    }
    switch currentGe2 + diceNum2 {//当前格子数 + 骰子数
    case geNum2://正好在终点格子上
        break gameLoop //结束gameLoop的while循环(如果break后面没有带上while循环的标签gameLoop,那么他仅仅是中断了switch语句)
    case let newSquare where newSquare > geNum2: //超过了终点格子--啥也不做,下一次循环
        continue gameLoop //结束本轮gameLoop循环,开始下一次gameLoop循环
    default://没有到终点、也没有超过终点
        currentGe2 += diceNum2 //每次都往前移动掷出来的骰子数个格子
        if currentGe2 < geArr2.count {//如果游戏没有结束
            currentGe2 += geArr2[currentGe2]// 额外再满足一下游戏的规则(上升或下滑)
            print("当前格子数是:\(currentGe2)")
        }
    }
}
print("带标签的游戏结束")

你可能感兴趣的:(07.Swift条件和循环语句)