我只是想创建一个简单的序列来隐藏存储在数组中的一些基础值。我似乎无法弄明白该怎么做。
我有一个私有Box
,其中包含String
和一些元数据。当我遍历NameList
时,我只想回到String
。
// A box to store private metadata with the element
fileprivate class Box {
var name: String
fileprivate var privateMetadata: Int
fileprivate init(name: String, metadata: Int) {
self.name = name
self.privateMetadata = metadata
}
}
// The public API to retrieve the list of elements
// I want to be able to iterate over NameList and get back only the `name` property.
// The private metadata should be hidden.
public class NameList: Sequence {
private var contents = [Box]()
func add(_ name: String) {
let metaData = ... // some function to generate private data
self.contents.append(Box(name: name, metadata: metaData))
}
// just want to get back the name property
func makeIterator() -> ??? {
???
}
}
答案 0 :(得分:1)
一种可能的解决方案是基于类型擦除的迭代器 (懒惰)将内容映射到其名称"属性:
public func makeIterator() -> AnyIterator<String> {
return AnyIterator(contents.lazy.map { $0.name }.makeIterator())
}
只是为了好玩:如果在迭代器上定义map
它返回一个迭代转换元素的新迭代器
extension IteratorProtocol {
func map<V>(_ transform: @escaping (Element) -> V) -> AnyIterator<V> {
var iter = self
return AnyIterator { return iter.next().map(transform) }
}
}
然后您可以将NameList.makeIterator()
方法实现为
public func makeIterator() -> AnyIterator<String> {
return contents.makeIterator().map { $0.name }
}