Swift 3 新增了两个全局函数:
sequence(first: next:) 和
sequence(state: next:)。使用它们可以返回一个无限序列。我们可以给他们一个初始值,或者初始状态,然后他们便会以懒加载的方式应用到一个闭包。下面通过样例分别演示这两个函数如何使用。
1,sequence(first: next:)介绍
1
2
|
//函数声明
public
func
sequence<t>(first:
T
, next:
@escaping
(
T
) ->
T
?) ->
UnfoldSequence
<
T
, (
T
?,
Bool
)>
|
假设我们打印出从1到100范围内所有的2的n次方数,过去我们使用
repeat...while 可以这么写:
1
2
3
4
5
|
var
i = 1
repeat {
print
(i)
i = i * 2
}
while
i <= 100
|
可以看到
repeat...while 循环依赖我外面声明的一个变量
i。
(1)而改用
sequence(first: next:) 实现如下,可以看到省去了外部变量的定义。
1
2
3
4
|
for
i
in
sequence(first: 1, next: { $0 * 2 }) {
if
i > 100 {
break
}
print
(i)
}
|
(2)我们还可以将所有的处理逻辑,状态判断都放在 next 闭包里。所以上面样例又可以这样写。
1
2
3
4
5
|
for
_
in
sequence(first: 1, next: {
print
($0)
let
value = $0 * 2
return
value <= 100 ? value :
nil
//next中返回nil表示sequence结束
}) {}
|
(3)从某一个树节点一直向上遍历到根节点
1
2
3
|
for
node
in
sequence(first: leaf, next: { $0.parent }) {
// node is leaf, then leaf.parent, then leaf.parent.parent, etc.
}
|
2,sequence(state: next:)
1
2
3
|
//函数声明
public
func
sequence<
T
,
State
>(state:
State
, next:
@escaping
(
inout
State
) ->
T
?)
->
UnfoldSequence
<
T
,
State
>
|
(1)下面样例通过指定最大的x轴,y轴坐标值,列出其内部所有的整点。
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
|
import
UIKit
class
ViewController
:
UIViewController
{
//命名一个坐标点类型
typealias
PointType
= (x:
Int
, y:
Int
)
override
func
viewDidLoad() {
super
.viewDidLoad()
//遍历序列并打印出所有坐标
for
point
in
cartesianSequence(xCount: 5, yCount: 3) {
print
(
"(x: \(point.x), y: \(point.y))"
)
}
}
//返回所有符合条件的坐标点序列
func
cartesianSequence(xCount:
Int
, yCount:
Int
) ->
UnfoldSequence
<
PointType
,
Int
> {
assert(xCount > 0 && yCount > 0,
"必须使用正整数创建序列。"
)
return
sequence(state: 0, next: {
(index:
inout
Int
) ->
PointType
?
in
guard index < xCount * yCount
else
{
return
nil
}
defer { index += 1 }
return
(x: index % xCount, y: index / xCount)
})
}
override
func
didReceiveMemoryWarning() {
super
.didReceiveMemoryWarning()
}
}
|
运行结果如下:
(2)假设我们有两个书架,一个里面是中文书、另一个里面是外文书。现在要返回一个交叉序列,即一本中文书、一本外文书这样交替显示。直到某个书柜的书显示完毕即结束。
运行结果如下:
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
59
60
61
62
|
import
UIKit
class
ViewController
:
UIViewController
{
override
func
viewDidLoad() {
super
.viewDidLoad()
//中文书架
let
bookShelf1 =
BookShelf
()
bookShelf1.append(book:
Book
(name:
"平凡的世界"
))
bookShelf1.append(book:
Book
(name:
"活着"
))
bookShelf1.append(book:
Book
(name:
"围城"
))
bookShelf1.append(book:
Book
(name:
"三国演义"
))
//外文书架
let
bookShelf2 =
BookShelf
()
bookShelf2.append(book:
Book
(name:
"The Kite Runner"
))
bookShelf2.append(book:
Book
(name:
"Cien anos de soledad"
))
bookShelf2.append(book:
Book
(name:
"Harry Potter"
))
//创建两个书架图书的交替序列
for
book
in
sequence(state: (
false
, bookShelf1.makeIterator(), bookShelf2.makeIterator()),
next: { (state:
inout
(
Bool
,
AnyIterator
<
Book
>,
AnyIterator
<
Book
>)) ->
Book
?
in
state.0 = !state.0
return
state.0 ? state.1.next() : state.2.next()
}) {
print
(book.name)
}
}
override
func
didReceiveMemoryWarning() {
super
.didReceiveMemoryWarning()
}
}
// 图书
struct
Book
{
var
name:
String
}
// 书架
class
BookShelf
{
//图书集合
private
var
books: [
Book
] = []
//添加新书
func
append(book:
Book
) {
self
.books.append(book)
}
//创建Iterator
func
makeIterator() ->
AnyIterator
<
Book
> {
var
index :
Int
= 0
return
AnyIterator
<
Book
> {
defer {
index = index + 1
}
return
index <
self
.books.count ?
self
.books[index] :
nil
}
}
}
|
原文出自: www.hangge.com 转载请保留原文链接: http://www.hangge.com/blog/cache/detail_1377.html