在 Swift 中實(shí)現(xiàn)循環(huán)/遍歷有如下幾種方式:
1.1 for-in
1.1.1 遍歷區(qū)間
1.1.1.1 順序遍歷
for index in 0 ..< 5 {
print(index)
}
輸出:
0
1
2
3
4
1.1.1.2 逆序遍歷
for index in (0 ... 5).reversed() {
print(index)
}
輸出:
5
4
3
2
1
0
1.1.1.3 嵌套 where 條件
for i in 1...10 where i%3 == 0{
print(i)
}
輸出 :
3
6
9
- 使用
..<指定半開區(qū)間,使用...指定閉區(qū)間 - 使用
range.reversed()來指定逆序循環(huán) - 如果在循環(huán)體中,不需要使用
index,則可以用_替換index
1.1.2 遍歷數(shù)組
1.1.2.1 順序遍歷
let test = [10,24,33,6,18]
for value in test {
print(value)
}
輸出:
10
24
33
6
18
1.1.2.2 逆序遍歷數(shù)組
let test = [10,24,33,6,18]
for value in test.reversed() {
print(value)
}
輸出:
18
6
33
24
10
1.1.2.3 同時(shí)遍歷數(shù)組的下標(biāo)和值
let test = [10,24,33,6,18]
for (index,value) in test.enumerated() {
print(index,value)
}
輸出:
0 10
1 24
2 33
3 6
4 18
那么,混合使用 reversed 與 enumerated 會有怎樣的情況?
test.enumerated().reversed()
依次輸出 (4 18) 至 (0...10)
test.reversed().enumerated()
依次輸出 (0 18) 至 (4...10)
1.1.3 遍歷字符串
var str = "Hello"
func test(){
for ch in str {
print(ch)
}
}
輸出 :
H
e
l
l
o
1.1.4 遍歷字典
var userDict:Dictionary<String,Int>=["張三":23,"李四":24,"王五":25]
//遍歷方式1:for-in 之間必須用小括號包裹內(nèi)容
for (key,value) in userDict{
print("\(key)的年齡為\(value)")
}
//f遍歷方式2:因?yàn)闃?gòu)建字典時(shí),實(shí)際是將鍵值對構(gòu)建成了Element對象,所以,elem就是這個(gè)對象
for elem in userDict {
print(elem)
print("\(elem.key)的年齡為\(elem.value)")
}
1.2 Array.forEach
let test = [10,24,33,6,18]
test.forEach { (value) in
print(value)
}
輸出:
10
24
33
6
18
- 使用
for-in循環(huán)時(shí),在循環(huán)體內(nèi)部調(diào)用return會直接結(jié)束循環(huán) - 使用
Array.forEach循環(huán)時(shí),在閉包內(nèi)調(diào)用return只會結(jié)束一次閉包調(diào)用
1.3 帶有步進(jìn)的遍歷
我們可以實(shí)現(xiàn) Strideable 協(xié)議,也可以使用 Strideable 協(xié)議中 stride 方法直接進(jìn)行循環(huán)操作
1.3.1 使用 stride(from,to,by)
順序循環(huán) 0 至 10(不包括10),依次遞增 2
for index in stride(from: 0, to: 10, by: 2) {
print(index)
}
輸出:
0
2
4
6
8
1.3.2、使用 stride(from,through,by)
逆序循環(huán),10 至 0(包括0),依次遞減 2
for index in stride(from: 10, through: 0, by: -2) {
print(index)
}
輸出:
10
8
6
4
2
0
1.3.3、使用 Strideable 協(xié)議
通常使用 stride 時(shí),我們傳遞的參數(shù)均為 Int ,當(dāng)我們想對自己定義的類型進(jìn)行循環(huán)時(shí),這樣的方式并不方便,好在我們可以使用 Strideable 協(xié)議解決這個(gè)問題
首先我們定義一個(gè)類,代表素?cái)?shù)
class Prime {
public var value:Int = 0
public init(_ v:Int) {
value = v
}
}
然后實(shí)現(xiàn) Strideable 協(xié)議。其中:
-
func distance(to other: Prime)表示兩個(gè)素?cái)?shù)之間素?cái)?shù)的個(gè)數(shù) -
func advanced(by n: Int) -> Prime返回第 n 個(gè)素?cái)?shù)
注意,此函數(shù)需要返回一個(gè)新的 Prime,不能修改自身的值
final class Prime : Strideable {
//協(xié)議
func distance(to other: Prime) -> Int {
var count = 0
for index in value ..< other.value {
if Prime(index).isPrime() {
count += 1
}
}
return count
}
//協(xié)議
func advanced(by n: Int) -> Prime {
let result = Prime(value)
var count = n
while true {
result.value += 1
if result.isPrime() {
count -= 1
}
if count == 0 {
break
}
}
return result
}
typealias Stride = Int
public var value:Int = 0
public init(_ v:Int) {
value = v
}
//判斷當(dāng)前值是否為素?cái)?shù)
private func isPrime()->Bool {
guard 2 <= value/2 else {
return true
}
return !((2 ... value/2).contains { (v) -> Bool in
return value % v == 0
})
}
}
使用 stride 輸出給定兩個(gè)素?cái)?shù)之間的所有素?cái)?shù)
let start = Prime(2)
let end = Prime(11)
for value in stride(from:start, through: end, by: 1) {
print(value.value)
}
輸出:
2
3
5
7
11
當(dāng)然,在實(shí)際使用中,需要直接繼承 Strideable 來實(shí)現(xiàn)循環(huán)的操作少之又少,我們只需要熟練使用其他的方式即可