Я могу написать Итераторы следующим образом:
enum Stage { case a, ab, end }
struct SetMaker<Input: Hashable>: Sequence, IteratorProtocol {
var a,b: Input
var stage = Stage.a
init(a: Input, b: Input) {
self.a = a
self.b = b
}
mutating func next() -> Set<Input>? {
switch stage {
case .a: stage = .ab; return Set<Input>([a])
case .ab: stage = .end; return Set<Input>([a,b])
case .end: return nil
}
}
}
let setMaker = SetMaker(a: "A", b: "B")
for x in setMaker {
print(x)
}
struct ArrayMaker<Input: Hashable>: Sequence, IteratorProtocol {
var a: Input
var b: Input
var stage = Stage.a
init(a: Input, b: Input) {
self.a = a
self.b = b
}
mutating func next() -> Array<Input>? {
switch stage {
case .a: stage = .ab; return Array<Input>([a])
case .ab: stage = .end; return Array<Input>([a,b])
case .end: return nil
}
}
}
let arrayMaker = ArrayMaker(a: "A", b: "B")
for x in arrayMaker {
print(x)
}
Первый возвращает последовательность наборов, а второй возвращает последовательность массивов.
Они оба работают нормально, но мне нравится держать мой код "СУХИМ" (т.е. не повторять себя).
Так что я хотел бы написать что-то общее, что позволит создать любой из них.
Моя попытка:
struct AnyMaker<Input: Hashable, CollectionType>: Sequence, IteratorProtocol {
var a,b: Input
var stage = Stage.a
init(a: Input, b: Input) {
self.a = a
self.b = b
}
mutating func next() -> CollectionType<Input>? {
switch stage {
case .a: stage = .ab; return CollectionType<Input>([a])
case .ab: stage = .end; return CollectionType<Input>([a,b])
case .end: return nil
}
}
}
Но это не компилируется.
Любая помощь приветствуется: -)
Редактировать ...
@ Роб сделал хорошее предложение, которое помогло мне отойти оттуда - см. Его ответ.
Но если я хочу, чтобы коллекция иногда была множеством, тогда возникает проблема, потому что Set не RangeReplaceable.
Другими словами, я создал немного другой код:
struct Pairs<C>: Sequence, IteratorProtocol
where C: RangeReplaceableCollection {
var collection: C
var index: C.Index
init(_ collection: C) {
self.collection = collection
index = self.collection.startIndex
}
mutating func next() -> C? {
guard index < collection.endIndex else { return nil }
let element1 = collection[index]
index = collection.index(after: index)
guard index < collection.endIndex else { return nil }
let element2 = collection[index]
let pair = [element1,element2]
return C(pair)
}
}
do {
print("Pairs from array")
let array = ["A","B","C"]
let pairs = Pairs(array) //This line is fine
for pair in pairs {
print(pair)
}
}
do {
print("Pairs from set")
let set = Set(["A","B","C"])
let pairs = Pairs(set) // This line causes error
for pair in pairs {
print(pair)
}
}
Строка let let = Pairs (set) генерирует ошибку:
«Тип аргумента« Set »не соответствует ожидаемому типу« RangeReplaceableCollection »»
Так что мне нужно разобраться, как создать экземпляр коллекции без использования RangeReplaceableCollection?