19

我正在尝试遍历 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,所以它应该可以正常工作吗?

4

3 回答 3

41

您可以使用以下命令迭代有序集

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)
}
于 2014-10-28T08:43:33.663 回答
2

NSOrderedSet不符合SequenceTypeNSOrderedSet是的子类,NSObject而不是NSSet人们想象的那样。我猜苹果工程师忽略了它。

于 2014-10-28T08:37:01.237 回答
2

根据文档,Swifty、最简单和最通用的解决方案是浅拷贝到 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

于 2015-01-09T22:20:05.413 回答