Swift Dictionary的自定义序列

我有一个容器类,它有一个基础字典。 我已经为这个类实现了下标来访问底层字典的成员。 现在,我正在尝试在这个类上创建一个序列,这样我就可以通过在类实例本身上使用’for-in’循环来迭代底层字典的所有元素。 我一直在寻找一些序列为Swift词典的例子,但找不到任何能很好地解释这些东西的东西。 我已经看到了Swift数组的一些自定义序列示例,但没有看到Swift Dictionary的自定义序列示例。 如果有人能解释我是如何实现这一点的,我真的很感激。 以下是该类的代码(没有序列代码,因为我不知道从哪里开始)

import Foundation class STCQuestionList : GeneratorType, SequenceType { private var questionDict: [String : STCQuestion] = [ : ]; subscript(key : String?) -> STCQuestion? { get { if (key != nil) { return self.questionDict[key!]; } return nil; } set(newValue) { if (key != nil) { self.questionDict[key!] = newValue; } } } func generate() -> GeneratorType { } func next() -> (String, STCQuestion)? { if (self.questionDict.isEmpty) { return .None } } } 

如果我理解正确,那么只是转发生成呢?

 func generate() -> DictionaryGenerator { return questionDict.generate() } 

(你不需要实现GeneratorType ,只需要SequenceType 。它的generate()本身返回一个GeneratorType就是next()实现的那个next() ,Dictionary中现有的generate()实现已经为你做了。)

基于您的代码的完整工作示例:

 // Playground - noun: a place where people can play import Foundation class STCQuestion { let foo: String init(_ foo: String) { self.foo = foo } } class STCQuestionList : SequenceType { private var questionDict: [String : STCQuestion] = [ : ]; subscript(key : String?) -> STCQuestion? { get { if key != nil { return self.questionDict[key!]; } return nil; } set(newValue) { if key != nil { self.questionDict[key!] = newValue; } } } func generate() -> DictionaryGenerator { return questionDict.generate() } } var list = STCQuestionList() list["test"] = STCQuestion("blah") list["another"] = STCQuestion("wibble") list["third"] = STCQuestion("doodah") for (key, value) in list { println("Key: \(key) Foo: \(value.foo)") } // Output: // Key: test Foo: blah // Key: another Foo: wibble // Key: third Foo: doodah 

注意:我重新考虑了这一点 – 通过编辑页面的原始答案…)

Swift有一个通用的GeneratorOf类型,可用于创建生成器。 您只需提供一个闭包,它返回初始值设定项中的下一个值:

 class STCQuestionList : SequenceType { private var questionDict: [String : STCQuestion] = [ : ]; subscript(key : String?) -> STCQuestion? { get { if (key != nil) { return self.questionDict[key!]; } return nil; } set(newValue) { if (key != nil) { self.questionDict[key!] = newValue; } } } /// Creates a generator for each (key, value) func generate() -> GeneratorOf<(String, STCQuestion)> { var index = 0 return GeneratorOf<(String, STCQuestion)> { if index < self.questionDict.keys.array.count { let key = self.questionDict.keys.array[index++] return (key, self.questionDict[key]!) } else { return nil } } } } 

如果你不关心顺序,你不能只调用相同的字典方法或使你的类成为字典的子类吗? 例如:

 func generate() -> GeneratorType { return self.questionDict.generate() } func next() -> (String, STCQuestion)? { return self.questionDict.next() }