2016-11-18 23 views
3

我一直在使用sort()函數,但它混合了相對順序。如何在swift中穩定排序數組?

這是我的代碼的外觀。

recipes.sort { $0.skill.value <= $1.skill.value } 

Swift API說:

的排序算法並不穩定。不穩定的排序可能會改變比較相等的元素的相對順序。

我該如何改變這一點,以便相對順序與以前保持一致?

+0

我打算髮表評論,這被稱爲「穩定排序」 - 但我看到你已經引用了使用這個短語的文檔。既然你遇到了表達你要找的東西的「藝術術語」,爲什麼你會用不同的,更模糊的措辭呢?你正在尋找一個穩定的排序。 –

+0

抱歉改變它。 – demiculus

+0

Swift在標準庫中沒有穩定的排序。快速谷歌搜索顯示一個類似的問題http://stackoverflow.com/questions/29322308/swift-stable-sort與一些解決方案,一個斯威夫特功能請求:https://bugs.swift.org/browse/SR-306和這篇文章:https://airspeedvelocity.net/2016/01/10/writing-a-generic-stable-sort/。 –

回答

3
 let sortedArray = (recipes as NSArray).sortedArray(options: .stable, usingComparator: { (lhs, rhs) -> ComparisonResult in 
      let lhs = (lhs as! Recipe) 
      let rhs = (rhs as! Recipe) 
      if lhs.skill.value == rhs.skill.value { 
       return ComparisonResult.orderedSame 
      } else if lhs.skill.value < rhs.skill.value { 
       return ComparisonResult.orderedAscending 
      } else { 
       return ComparisonResult.orderedDescending 
      } 
     }) 

從這裏拿了:https://medium.com/@cocotutch/a-swift-sorting-problem-e0ebfc4e46d4

5

低於剛工作就像在標準庫中的sorted方法,而無需額外限制的執行情況。

extension RandomAccessCollection { 

    /// return a sorted collection 
    /// this use a stable sort algorithm 
    /// 
    /// - Parameter areInIncreasingOrder: return nil when two element are equal 
    /// - Returns: the sorted collection 
    public func stableSorted(by areInIncreasingOrder: (Iterator.Element, Iterator.Element) -> Bool?) -> [Iterator.Element] { 

     let sorted = self.enumerated().sorted { (one, another) -> Bool in 
      if let result = areInIncreasingOrder(one.element, another.element) { 
       return result 
      } else { 
       return one.offset < another.offset 
      } 
     } 
     return sorted.map{ $0.element } 
    } 
} 

穩定的排序需要保留原始順序。所以我們給每一個元素賦予除了它的值,索引之外的順序的權重,然後原始的排序方法就會起作用,因爲永遠不會有2個相等的元素。