2015-03-28 10 views
5

W tej chwili (28 marca 2015 r.): Jeśli chcę używać stabilnego sortowania w szybkim tempie, muszę użyć NSArray i sortWithOptions lub napisać własny stabilny sort w Swift, taki jak insertion sort? Rozumiem, że sorted jest niestabilny.Swift Stabilny sort?

Example of stable sort in NSMutableArray:

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

jestem brakuje innej opcji, które są dostępne do mnie w Swift inny niż przy użyciu Objective-C lub pisząc własne rodzaju?

+0

tak, możesz też napisać wrapper, który wywołuje funkcję -c - jeśli naprawdę jeszcze nie ma ... – Michael

+0

oczywiście! Miałem mózgowy pierdziel. Uczyń tę odpowiedź, a ja sprawdzę zielony znak, @ Michael. :) – finneycanhelp

+2

ok ........... :) – Michael

Odpowiedz

0

Jak @Michael umieścić go można "napisać SWIFT-wrapper, który wywołuje funkcję objective-c"

0

Oprócz swojej Swift podejścia otoki można używać funkcji C mergesort:

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"] 

lub napisać Czysta Swift podejście, które sprawia, że ​​rzeczy bardziej ogólna: (. to jest moje skromne i proste podejście, bez wątpienia inni mogą zoptymalizować)

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"]