好的,所以我有一个包含一组结果的CollectionType
类,可以像数组一样访问每个结果。
但是,并非所有结果都适用于所有情况,因此有时只需要获取第一个元素,而其他代码可能只想调用其他值。我将尝试通过一个例子说明这一点(请原谅任何基本错误):
class MyClass: CollectionType {
typealias Index = Int
let startIndex: Index = 0
let endIndex: Index
// Initialiser here (setting self.endIndex)
func generate() -> IndexingGenerator<MyClass> {
return IndexingGenerator(self)
}
subscript(theIndex: Index) -> String { /* Get value at given index. */ }
var first: String { return self[0] }
}
我真正想做的是创建一个计算属性others
,它本身就像一个集合,但省略了主结果对象中的第一项,所以我可以这样做:
let first = myClassInstance.first
for item in myClassInstance.others { /* Do something */ }
我已经大大简化了这个例子,所以不,我担心我不能只使first
成为一个存储的属性,或者以某种方式将结果分开;结果既是完整的,也是上面分离的格式,用于不同的目的,我想避免代码使用这个类必须知道他们需要哪些索引(通常他们只需要全套结果,或first
或others
)之一
所以,无论如何,考虑到这一点,我最好的方法是添加others
计算属性?
答案 0 :(得分:1)
如果您对others
只是一个序列感到满意(那么支持for…in
,map
,filter
等),您可以这样做:< / p>
class MyClass: CollectionType {
var others: SequenceOf<String> {
return SequenceOf { ()->GeneratorOf<String> in
var g = self.generate()
// the following fiddlyness courtesy of the requirement
// not to call .next() a second time after it returns nil...
if g.next() != nil {
return GeneratorOf { g.next() }
}
else {
return GeneratorOf { nil }
}
}
}
}
let mc = MyClass()
for item in mc.others {
println(item)
}
根据您保存内部数据的方式,您可以通过返回内部数据片段的生成器来简化这一过程。
如果您想要一些返回集合而不仅仅是序列的东西,请考虑使您的集合符合Sliceable
。然后,您可以使用dropFirst(self)
。
P.S。为了与Swift std lib的其余部分保持一致,你应该考虑让first
在空集合的情况下返回一个可选项:var first: String? { return Swift.first(self) }
。即使您的实现保证至少有一个条目,一致性也可能是值得的。