Итерирование по NSOrderedSet

Я пытаюсь перебрать экземпляр NSOrderedSet. Что-то вроде этого:

func myFunc() {
    var orderedSet = NSOrderedSet(array: [ 42, 43, 44])

    for n in orderedSet {
        NSLog("%i", n)
    }
}

... однако строка цикла for создает эту ошибку компилятора:

'NSOrderedSet' does not have a member named 'Generator'

Теперь я могу преобразовать его в массив следующим образом:

    for n in orderedSet.array {
        NSLog("%i", n)
    }

... но я подумал, есть ли лучшее решение?

Я также хочу понять, почему можно перебирать набор, но не упорядоченный набор? NSOrderedSet реализует NSFastEnumeration, поэтому он должен работать правильно?

Ответы

Ответ 1

Вы можете выполнять итерацию по упорядоченному набору с помощью

let orderedSet = NSOrderedSet(array: [ 42, 43, 44])
orderedSet.enumerateObjectsUsingBlock { (elem, idx, stop) -> Void in
    println("\(idx): \(elem)")
}

ОБНОВЛЕНИЕ: По состоянию на Swift 1.2 (Xcode 6.3), NSOrderedSet соответствует SequenceType и можно перечислить с помощью for ... in ...:

let orderedSet = NSOrderedSet(array: [ 42, 43, 44])
for elem in orderedSet {
    println(elem)
}

Ответ 2

NSOrderedSet не соответствует SequenceType. NSOrderedSet является подклассом NSObject, а не NSSet, как можно было бы себе представить. Я думаю, инженеры Apple не обратили на это внимания.

Ответ 3

Самое свежее, простое и наиболее общее решение - это мелкая копия массива в O (1) - для документов. Это позволит вам использовать другие функциональные методы и функции Swift.

import Swift
import Foundation


println("Simplest, most accessible, O(1) performance: shallow copy to array:")

var set = NSOrderedSet(array: map(0...7) { d in d })
for d in set.array as [Int] {
    print("\t\(d)")
}

println("\n\nIn general - for other types and cases, you could create a sequence:")

extension NSOrderedSet {
    func sequenceOf<T>(t:T.Type) -> SequenceOf<T> {
        var current = 0
        return SequenceOf(GeneratorOf({ () -> T? in
            return current < self.count ? self.objectAtIndex(current++) as? T : nil
        }))
    }
}

for d in set.sequenceOf(Int.self) {
    print("\t\(d)")
}

Простейшая, наиболее доступная, O (1) производительность: мелкая копия в массив:

0 1 2 3 4 5 6 7

В общем - для других типов и случаев вы можете создать последовательность:

0 1 2 3 4 5 6 7