我为 Swift 创建了一个扩展,Array
以使 Swift 以这种方式使用起来非常干净。
import Foundation
extension Array where Element: AnyObject {
public func indexOfObject<T: AnyObject>(obj: T, options opts: NSBinarySearchingOptions, usingComparator cmp: (T, Element) -> NSComparisonResult) -> Int {
return (self as NSArray).indexOfObject(obj, inSortedRange: NSRange(0..<count), options: opts, usingComparator: { (a: AnyObject, b: AnyObject) -> NSComparisonResult in
if a === obj {
return cmp(a as! T, b as! Element)
} else {
var result = cmp(b as! T, a as! Element)
if result == .OrderedDescending {
result = .OrderedAscending
} else if result == .OrderedAscending {
result = .OrderedDescending
}
return result
}
})
}
}
这是一个示例用法:
class ItemWithProperty {
var property: Int
init(property: Int) {
self.property = property
}
}
let listOfItems = [ItemWithProperty(property: 1),
ItemWithProperty(property: 20),
ItemWithProperty(property: 30),
ItemWithProperty(property: 45),
ItemWithProperty(property: 45),
ItemWithProperty(property: 45),
ItemWithProperty(property: 60),
ItemWithProperty(property: 77),
]
let indexOf20 = listOfItems.indexOfObject(20, options: .FirstEqual) { number, item in
number.compare(item.property)
}
// returns 1
let indexOf25 = listOfItems.indexOfObject(25, options: .FirstEqual) { number, item in
number.compare(item.property)
}
indexOf25 == NSNotFound
// comparison is true, number not found
let indexOfFirst45 = listOfItems.indexOfObject(45, options: .FirstEqual) { number, item in
number.compare(item.property)
}
// returns 3
let indexOfLast45 = listOfItems.indexOfObject(45, options: .LastEqual) { number, item in
number.compare(item.property)
}
// returns 5
let indexOf77 = listOfItems.indexOfObject(77, options: .FirstEqual) { number, item in
number.compare(item.property)
}
// returns 7