Swift Sequence Iterator,它隐藏了一个Array中的一些底层值

时间:2017-10-31 15:24:19

标签: swift iterator sequence

我只是想创建一个简单的序列来隐藏存储在数组中的一些基础值。我似乎无法弄明白该怎么做。

我有一个私有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() -> ??? {
         ???
     }
}

1 个答案:

答案 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 }
}