序列

  • 首先序列有一些默认实现的方法,比如遍历相关的map,filter、reduce、foreach方法,还有与子序列相关的prefix、suffix、split、dropFirst、dropLast方法。通过迭代可以在序列或集合上执行大量的操作,甚至可以包装成(协议或集合扩展的)方法,不需要再迭代就可以对序列货集合上的值进行顺序访问或操作。

  • 序列通过创建一个迭代器来提供对元素的访问。迭代器每次迭代序列产生一个值,并且在遍历序列时对遍历状态进行管理。很少直接使用迭代器,一般forin是更管用的方法。一些算法中可能会直接调用迭代器。


创建序列的方法:

1⃣️最基本一种,添加sequence和IteratorProtocol协议的一致性并实现协议的方法。
记住你必须要设置一个遍历的初始状态在序列或者迭代器中,不管是在next还是初始化器、属性中。

struct FibsIterator: IteratorProtocol {//迭代器
    var state = (0, 1)
    mutating func next() -> Int? {//可能会是无限的,一般最终会返回nil然后结束迭代。
        let upcomingNumber = state.0
        state = (state.1, state.0 + state.1)
        return upcomingNumber
    }
}

struct FibsSequence: Sequence {//序列
    func makeIterator() -> FibsIterator {
        return FibsIterator()
    }
}

for i in fibsSequence.prefix(10)

2⃣️序列又作为迭代器时,Swift会默认实现makeIterator()方法。但要添加sequence和IteratorProtocol协议的一致性。

struct Countdown: Sequence, IteratorProtocol {
    var count: Int
    mutating func next() -> Int? {
        if count == 0 {
            return nil
        } else {
            defer { count -= 1 }
            return count
        }
    }
}
let threeToGo = Countdown(count: 5)
for i in threeToGo {
    print(i)
}

3⃣️将值类型迭代器“类型抹除” (不暴露具体实现)后包装到引用类型的内部对象中,再封装成AnyIterator迭代器。【AnyIterator、AnySequence都是引用类型】
AnyIterator有2个初始化器方法,初始化器直接接受值类型的迭代器,或者接受一个next函数作为参数。同样AnySequence可以通过其他序列或者接受返回为AnyIterator的函数作为输入。

var x = 7
let iterator: AnyIterator<Int> = AnyIterator {
    defer { x += 1 }
    return x < 15 ? x : nil
}
let a = Array(iterator)
a == [7, 8, 9, 10, 11, 12, 13, 14]

let seq = stride(from: 0, to: 10, by: 1)
var i1 = seq.makeIterator()
iterator = AnyIterator(i1)

let iteratorFuc: () -> AnyIterator<Int> = {
    return iterator
}
let anySequence = AnySequence(iteratorFuc)
let anySeq = AnySequence(seq)

4⃣️通过函数创建Swift系统序列,StrideThrough 和 StrideTo的实例(浮点数或整型)是使用函数stride(from: 0, to: 10, by: 1)和stride(from: 0, through: 10, by: 1)创建的。

let seq = stride(from: 0, to: 10, by: 1)//不包括10
//stride(from: 0, through: 10, by: 1)包括10当且仅当跨越最后一步正好落在10
//stride(from: 0, to: 10, by: -1)不会发生迭代产生任何值
//stride(from: 3, to: 0, by: -1)向下步进发生迭代
var i1 = seq.makeIterator()
while let i = i1.next() {
    print(i)
}

5⃣️通过函数创建自定义序列,UnfoldSequence的实例是使用函数sequence(first:next:)sequence(state:next:)创建的。可以用它sequence(state:next:)来替代AnyIterator来创建AnySequence【UnfoldSequence<T,State>】序列。(除了4⃣️其他都可能是无限的序列)。
两个函数的返回类型都是UnfoldSequence<T,State>,这两个函数的操作在函数式编程中被称为展开(Unfold),两个函数将一个单一的值展开形成一个序列。sequence(first:next:)函数可以用来处理在c语言中’ for '循环处理的场景。

//`sequence(first:next:)`内部是用`sequence(state:next:)实现的,所以会出现遗漏first的情况,会直接返回接受first参数的next闭包计算后的值。在`sequence(state:next:)的闭包参数内部我们通过枚举匹配和使用一个布尔值来解决这个问题。(序列从第二个值开始,迭代器没有返回first)。
//内部是用的是`sequence(state:next:)实现的。序列是从first 1开始的。
 for value in sequence(first: 1, next: { $0 * 2 }) {
    value is 1, then 2, then 4, then 8, etc.
}


//利用可变的‘state’变量返回的序列是由‘next’闭包重复地延迟计算产生的值构成。
// 产生的新序列是state中的两个序列交错迭代的返回值构成

sequence(state: (false, seq1.makeIterator(), seq2.makeIterator()), next: { iters in
    iters.0 = !iters.0
    return iters.0 ? iters.1.next() : iters.2.next()
})
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容