栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

提供给函数的优雅解决方案每次都调用数组的不同元素(有序并在所有返回时从新开始)?

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

提供给函数的优雅解决方案每次都调用数组的不同元素(有序并在所有返回时从新开始)?

“弹出”的过程实际上是自定义序列的迭代。在Swift中表示这种情况的适当方式是作为实现的类型(

struct
/
class
IteratorProtocol
。我打电话给我
CycleIterator
。迭代器很少直接使用。而是通常由符合的类型提供
Sequence
。我打电话给我
CycleSequence

Sequence
协议只需要使用符合条件的类型来提供一个函数
makeIterator()
,该函数会返回一个迭代器(
CycleIterator
在我的情况下)。只需执行此操作,即可立即获得序列的所有功能。Iterability,
map
/
filter
/
reduce
prefix
suffix
等。

IteratorProtocol
只要求这种类型提供一个函数,
next()
,这产生一个返回
Element?
。返回值是可选的,
nil
用于表示序列的结尾。

这是我将如何实现这些方法:

public struct CycleSequence<C: Collection>: Sequence {    public let cycledElements: C    public init(cycling cycledElements: C) {        self.cycledElements = cycledElements    }    public func makeIterator() -> CycleIterator<C> {        return CycleIterator(cycling: cycledElements)    }}public struct CycleIterator<C: Collection>: IteratorProtocol {    public let cycledElements: C    public private(set) var cycledElementIterator: C.Iterator    public init(cycling cycledElements: C) {        self.cycledElements = cycledElements        self.cycledElementIterator = cycledElements.makeIterator()    }    public mutating func next() -> C.Iterator.Element? {        if let next = cycledElementIterator.next() { return next        } else { self.cycledElementIterator = cycledElements.makeIterator() // Cycle back again return cycledElementIterator.next()        }    }}let s1 = CycleSequence(cycling: [1, 2, 3]) // Works with arrays of numbers, as you would expect.// Taking one element at a time, manuallyvar i1 = s1.makeIterator()print(i1.next() as Any) // => Optional(1)print(i1.next() as Any) // => Optional(2)print(i1.next() as Any) // => Optional(3)print(i1.next() as Any) // => Optional(1)print(i1.next() as Any) // => Optional(2)print(i1.next() as Any) // => Optional(3)print(i1.next() as Any) // => Optional(1)let s2 = CycleSequence(cycling: 2...5) // Works with any Collection. Ranges work!// Taking the first 10 elementsprint(Array(s2.prefix(10))) // => [2, 3, 4, 5, 2, 3, 4, 5, 2, 3]let s3 = CycleSequence(cycling: "abc") // Strings are Collections, so those work, too!s3.prefix(10).map{ "you can even map over me! ($0)" }.forEach{ print($0) }print(Array(CycleSequence(cycling: [true, false]).prefix(7))) // => [true, false, true, false, true, false, true]print(Array(CycleSequence(cycling: 1...3).prefix(7))) // => [1, 2, 3, 1, 2, 3, 1]print(Array(CycleSequence(cycling: "ABC").prefix(7))) // => ["A", "B", "C", "A", "B", "C", "A"]print(Array(CycleSequence(cycling: EmptyCollection<Int>()).prefix(7))) // => []print(Array(zip(1...10, CycleSequence(cycling: "ABC")))) // => [(1, "A"), (2, "B"), (3, "C"), (4, "A"), (5, "B"), (6, "C"), (7, "A"), (8, "B"), (9, "C"), (10, "A")]

这是一个简短的替代实现,展示了如何

sequence(state:next:)
用于实现相似的目标。

func makeCycleSequence<C: Collection>(for c: C) -> AnySequence<C.Iterator.Element> {    return AnySequence(        sequence(state: (elements: c, elementIterator: c.makeIterator()), next: { state in if let nextElement = state.elementIterator.next() {     return nextElement } else {     state.elementIterator = state.elements.makeIterator()     return state.elementIterator.next() }        })    )}let repeater = makeCycleSequence(for: [1, 2, 3])print(Array(repeater.prefix(10)))


转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/649753.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号