Swift稳定排序?

fin*_*elp 5 sorting ios swift

在这个时候(2015年3月28日):如果我想在迅速用一个稳定的排序,我不得不使用NSArraysortWithOptions或写在斯威夫特我自己的稳定排序,如插入排序?我在Apple Swift文档中看到sorted的并不稳定.

NSMutableArray中稳定排序的示例:

[array sortWithOptions:NSSortStable usingComparator:^NSComparisonResult(id obj1, id obj2) {
    return [obj1 compare:obj2];
}];
Run Code Online (Sandbox Code Playgroud)

除了使用Objective-C或编写自己的排序之外,我是否错过了Swift中可用的其他选项?

ske*_*ech 0

除了 Swift 包装器方法之外,您还可以使用 Cmergesort:函数

var array2 = ["mango", "apple", "pear", "apple", "orange", "banana"]
mergesort(&array2, array2.count, MemoryLayout<String>.size, {
    let a = $0.unsafelyUnwrapped.load(as:String.self)
    let b = $1.unsafelyUnwrapped.load(as:String.self)
    if a == b {
        return 0
    }
    else if a < b {
        return -1 }
    else {
        return 1
    }
})
print(array2) // ["apple", "apple", "banana", "mango", "orange", "pear"]
Run Code Online (Sandbox Code Playgroud)

或者编写一个 Pure Swift 方法,使事情变得更加通用:

var array = ["mango", "apple", "pear", "banana", "orange", "apple", "banana"]

enum SortType {
    case Ascending
    case Descending
}

struct SortObject<T> {
    let value:T
    let startPosition:Int
    var sortedPosition:Int?
}

func swiftStableSort<T:Comparable>(array:inout [T], sortType:SortType = .Ascending) {

    var sortObjectArray = array.enumerated().map{SortObject<T>(value:$0.element, startPosition:$0.offset, sortedPosition:nil)}

    for s in sortObjectArray {
        var offset = 0
        for x in array[0..<s.startPosition]  {
            if s.value < x {
                offset += sortType == .Ascending ? -1 : 0
            }
            else if s.value > x {
                offset += sortType == .Ascending ? 0 : -1
            }
        }

        for x in array[s.startPosition+1..<array.endIndex]  {
            if s.value > x  {
                offset += sortType == .Ascending ? 1 : 0
            }
            else if s.value < x  {
                offset += sortType == .Ascending ? 0 : 1
            }
        }
        sortObjectArray[s.startPosition].sortedPosition = offset + s.startPosition
    }

    for s in sortObjectArray {
        if let sInd = s.sortedPosition {
            array[sInd] = s.value
        }
    }

}

swiftStableSort(array: &array, sortType:.Ascending) // ["apple", "apple", "banana", "banana", "mango", "orange", "pear"]
swiftStableSort(array: &array, sortType:.Descending) // ["pear", "orange", "mango", "banana", "banana", "apple", "apple"]
Run Code Online (Sandbox Code Playgroud)

(这是我简单粗暴的做法,无疑其他人可以优化。)