本章内容概览:Swift中的控制流、集合(数组、Set、字典)
上一节:【iOS】02_Swift基础语法(类与结构体、函数式)
下一节:【iOS】04_Swift基础语法(操作符)
同系列文章请查看:快乐码元 - iOS篇
Ⅰ.控制流
1.If 语句
1.1 if…else
1 2 3 4 5 6 let s = "hi" if s.isEmpty { print ("String is Empty" ) } else { print ("String is \(s) " ) }
1.2 三元条件
1 s.isEmpty ? print ("String is Empty again" ) : print ("String is \(s) again" )
1.3 if let-else
1 2 3 4 5 6 7 8 9 10 11 12 func f (s : String ?) { if let s1 = s { print ("s1 is \(s1) " ) } else { print ("s1 is nothing" ) } let s2 = s ?? "nothing" print ("s2 is \(s2) " ) } f(s: "something" ) f(s: nil )
1.3 if case let
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 enum E { case c1(String ) case c2([String ]) func des () { switch self { case .c1(let string): print (string) case .c2(let array): print (array) } } } E .c1("enum c1" ).des()E .c2(["one" , "two" , "three" ]).des()
2.Guard 语句
更好地处理异常情况
2.1 guard
1 2 3 4 5 6 7 8 9 func f1 (p : String ) -> String { guard p.isEmpty != true else { return "Empty string." } return "String \(p) is not empty." } print (f1(p: "" )) print (f1(p: "lemon" ))
2.2 guard let
1 2 3 4 5 6 7 8 9 func f2 (p1 : String ?) -> String { guard let p2 = p1 else { return "Nil." } return "String \(p2) is not nil." } print (f2(p1: nil )) print (f2(p1: "lemon" ))
3.For-in 遍历
3.1 基本遍历数组
1 2 3 4 let a = ["one" , "two" , "three" ]for str in a { print (str) }
3.2 使用下标范围
1 2 3 for i in 0 ..< 10 { print (i) }
3.3 使用 enumerated
1 2 3 for (i, str) in a.enumerated() { print ("第\(i + 1 ) 个是:\(str) " ) }
3.4 for in where
1 2 3 for str in a where str.prefix(1 ) == "t" { print (str) }
字典 for in,遍历是无序的:
1 2 3 4 5 6 7 8 let dic = [ "one" : 1 , "two" : 2 , "three" : 3 ] for (k, v) in dic { print ("key is \(k) , value is \(v) " ) }
3.5 stride
1 2 3 4 5 6 7 8 9 10 11 for i in stride (from: 10 , through: 0 , by: - 2 ) { print (i) }
4.While 语句
4.1 while
1 2 3 4 5 var i1 = 10 while i1 > 0 { print ("positive even number \(i1) " ) i1 -= 2 }
4.2 repeat while
1 2 3 4 5 var i2 = 10 repeat { print ("positive even number \(i2) " ) i2 -= 2 } while i2 > 0
使用 break 结束遍历,使用 continue 跳过当前作用域,继续下个循环
4.3 Switch 语句
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 func f1 (pa : String , t :(String , Int )) { var p1 = 0 var p2 = 10 switch pa { case "one" : p1 = 1 case "two" : p1 = 2 fallthrough default : p2 = 0 } print ("p1 is \(p1) " ) print ("p2 is \(p2) " ) switch t { case ("0" , 0 ): print ("zero" ) case ("1" , 1 ): print ("one" ) default : print ("no" ) } } f1(pa: "two" , t:("1" , 1 )) enum E { case one, two, three, unknown(String ) } func f2 (pa : E ) { var p: String switch pa { case .one: p = "1" case .two: p = "2" case .three: p = "3" case let .unknown(u) where Int (u) ?? 0 > 0 : p = u case .unknown(_ ): p = "negative number" } print (p) } f2(pa: E .one) f2(pa: E .unknown("10" )) f2(pa: E .unknown("-10" ))
Ⅱ.集合
1.数组
数组是有序集合
1 2 3 4 var a0: [Int ] = [1 , 10 ]a0.append(2 ) a0.remove(at: 0 ) print (a0)
1.1 difference
找两个集合的不同
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 let dif = a1.difference(from: a2) for c in dif { switch c { case .remove(let o, let e, let a): print ("offset:\(o) , element:\(e) , associatedWith:\(String(describing: a)) " ) case .insert(let o, let e, let a): print ("offset:\(o) , element:\(e) , associatedWith:\(String(describing: a)) " ) } } let a3 = a2.applying(dif) ?? [] print (a3)
swift的 diffing 算法在这 http://www.xmailserver.org/diff2.pdf
swift实现在 swift/stdlib/public/core/Diffing.swift
dif 有第三个 case 值 .insert(let offset, let element, let associatedWith) 可以跟踪成对的变化,用于高级动画。
1.2 从数组中随机取一个元素
1 print (a0.randomElement() ?? 0 )
1.3 数组排序
1 2 3 4 5 6 7 8 9 10 11 struct S1 { let n: Int var b = true } let a4 = [ S1 (n: 1 ), S1 (n: 10 ), S1 (n: 3 ), S1 (n: 2 ) ]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 let a5 = a4.sorted { i1, i2 in i1.n < i2.n } for n in a5 { print (n) } let a6 = [1 ,10 ,4 ,7 ,2 ]print (a6.sorted(by: > ))
可以加到数组扩展中,通过扩展约束能够指定特定元素类型的排序,代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 extension Array where Element == Int { func intSortedASC () -> [Int ] { return self .sorted(by: < ) } func intSortedDESC () -> [Int ] { return self .sorted(by: < ) } } print (a6.intSortedASC())
1.4 数组检索
在数组中检索满足条件的元素。
第一个满足条件了就返回:
1 2 3 4 5 let a7 = a4.first { $0 .n == 10 } print (a7? .n ?? 0 )
是否都满足了条件:
1 2 print (a4.allSatisfy { $0 .n == 1 }) print (a4.allSatisfy(\.b))
找出最大的那个:
1 2 3 4 print (a4.max(by: { e1, e2 in e1.n < e2.n }) ?? S1 (n: 0 ))
看看是否包含某个元素:
1 2 3 4 print (a4.contains(where: { $0 .n == 7 }))
1.5 切割数组
切片:
1 2 3 print (a6[..< 3 ]) print (a6.prefix(30 ))
去掉前3个:
prefix(while:)
和 drop(while:)
方法,顺序遍历执行闭包里的逻辑判断,满足条件就返回,遇到不匹配就会停止遍历。prefix 返回满足条件的元素集合,drop 返回停止遍历之后那些元素集合:
1 2 3 4 5 6 7 8 9 let a8 = [8 , 9 , 20 , 1 , 35 , 3 ]let a9 = a8.prefix { $0 < 30 } print (a9) let a10 = a8.drop { $0 < 30 } print (a10)
比 filter 更高效的删除元素的方法 removeAll
:
1 2 3 4 5 6 7 8 9 10 var a11 = [1 , 3 , 5 , 12 , 25 ]a11.removeAll { $0 < 10 } print (a11) let a12 = (0 ... 4 ).map { _ in Int .random(in: 0 ... 5 ) } print (a12)
1.6 #if
#if 用于后缀表达式
1 2 3 4 5 6 7 let a13 = a11#if os(iOS) .count #else .reduce(0 , + ) #endif print (a13)
2.Sets Set<Int>
Set 是无序集合,元素唯一
2.1 常见方法
1 2 3 4 5 6 7 8 9 10 11 12 let s0: Set <Int > = [2 , 4 ]let s1: Set = [2 , 10 , 6 , 4 , 8 ]let s2: Set = [7 , 3 , 5 , 1 , 9 , 10 ]let s3 = s1.union(s2) let s4 = s1.intersection(s2) let s5 = s1.subtracting(s2) let s6 = s1.symmetricDifference(s2) print (s3) print (s4) print (s5) print (s6)
1 2 3 4 print (s0.isSubset(of: s1)) print (s1.isSuperset(of: s0))
1 2 3 let s7: Set = [3 , 5 ]print (s0.isDisjoint(with: s7))
2.2 可变 Set
1 2 3 4 var s8: Set = ["one" , "two" ]s8.insert("three" ) s8.remove("one" ) print (s8)
3.字典 [:]
字典是无序集合,键值对应。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 var d1 = [ "k1" : "v1" , "k2" : "v2" ] d1["k3" ] = "v3" d1["k4" ] = nil print (d1) for (k, v) in d1 { print ("key is \(k) , value is \(v) " ) }
1 2 3 if d1.isEmpty == false { print (d1.count) }
3.1 遍历value
1 2 3 4 5 let d2 = d1.mapValues { $0 + "_new" } print (d2)
3.2 对字典的值或键进行分组
1 2 3 4 5 let d3 = Dictionary (grouping: d1.values) { $0 .count } print (d3)
3.3 字典取值
从字典中取值,如果键对应无值,则使用通过 default
指定的默认值
1 2 3 4 d1["k5" , default : "whatever" ] += "." print (d1["k5" ] ?? "" ) let v1 = d1["k3" , default : "whatever" ]print (v1)
3.4 compactMapValues
compactMapValues()
对字典值进行转换 和解包 。可以解可选类型,并去掉 nil 值 .
1 2 3 4 5 6 7 8 9 10 11 let d4 = [ "k1" : 1 , "k2" : 2 , "k3" : nil ] let d5 = d4.mapValues { $0 }let d6 = d4.compactMapValues{ $0 }print (d5)print (d6)
参考资料:
Tips:
Please indicate the source and original author when reprinting or quoting this article.