Ble*_*pes 5 arrays swift swift-playground
尝试扩展Array类型以使用二进制排序按顺序插入元素.这是我的游乐场代码:
extension Array {
func insertionIndexOf(elem: T , isOrderedBefore: (T, T) -> Bool) -> Int {
var lo = 0
var hi = self.count - 1
while lo <= hi {
let mid = (lo + hi)/2
if isOrderedBefore(self[mid], elem) {
lo = mid + 1
} else if isOrderedBefore(elem, self[mid]) {
hi = mid - 1
} else {
return mid
}
}
return 0
}
mutating func insertOrdered(elem: T){
let index = self.insertionIndexOf(elem, isOrderedBefore: { (a , b) in return (a > b) } )
return insert(elem, atIndex: index)
}
Run Code Online (Sandbox Code Playgroud)
}
我得到一个编译器错误:"无法使用类型的参数列表调用insertionIndexOf(T,isOrderedBefore:(_,_) - > _)"
奇怪的是,如果我改用:
mutating func insertOrdered(elem: T){
let index = self.insertionIndexOf(elem, isOrderedBefore: { (a , b) in return false } )
return insert(elem, atIndex: index)
}
Run Code Online (Sandbox Code Playgroud)
编译器平静下来,但数组插入不会被命令,:(当然.请任何想法?谢谢.
(使用Xcode 6.3 beta 2 - Swift 1.2)
从Swift 2开始,这可以通过协议扩展方法实现:
extension CollectionType where Generator.Element : Comparable, Index == Int {
func insertionIndexOf(elem: Generator.Element) -> Int {
var lo = 0
var hi = self.count - 1
while lo <= hi {
let mid = (lo + hi)/2
if self[mid] < elem {
lo = mid + 1
} else if elem < self[mid] {
hi = mid - 1
} else {
return mid // found at position mid
}
}
return lo // not found, would be inserted at position lo
}
}
extension RangeReplaceableCollectionType where Generator.Element : Comparable, Index == Int {
mutating func insertOrdered(elem: Generator.Element) {
let index = self.insertionIndexOf(elem)
self.insert(elem, atIndex: index)
}
}
Run Code Online (Sandbox Code Playgroud)
例:
var ar = [1, 3, 5, 7]
ar.insertOrdered(6)
print(ar) // [1, 3, 5, 6, 7]
Run Code Online (Sandbox Code Playgroud)
这些方法不是struct Array直接定义的,而是针对某些Array符合的协议,并提供必要的方法.
对于第一种方法,那是CollectionType因为它提供了(读取)下标访问,并且需要集合元素类型Comparable.
第二种方法改变了集合,这里RangeReplaceableCollectionType需要更严格的协议
.
您正在尝试评估a > b,但T可能不会Comparable。今天不可能编写这样的扩展。您希望能够说的是:
extension Array where T: Comparable {
Run Code Online (Sandbox Code Playgroud)
但目前在 Swift 中这是不可能的。编译器团队已表示这是一个优先事项,但我们不知道什么时候会出现在 Swift 上。
最好的方法是使其成为一个函数:
func insertOrdered<T: Comparable>(inout xs: [T], x: T)
Run Code Online (Sandbox Code Playgroud)
或者创建一个具有数组的新对象:
struct OrderedArray<T: Comparable> : ... {
var values: [T]
func insertionIndexOf(elem: T , isOrderedBefore: (T, T) -> Bool) -> Int
mutating func inserOrdered(elem: T)
...
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
567 次 |
| 最近记录: |