2017-02-27 48 views
0

我試圖通過比較它們的特定鍵來實現以下方法來刪除字典數組中的重複條目。然而,這種擴展方法是行不通的,由於錯誤:對值爲可Equatable的字典序列的擴展

Binary operator == cannot be applied to two 'Equatable' operands

這些顯然equatable和同一類型(Iterator.Element.Value),那麼,爲什麼不工作?

我看到它將Equatable視爲特定類型,而不是約束。我不能使它與泛型類型或通過編寫where Iterator.Element == [String: Any], Iterator.Element.Value: Equatable

你們有沒有關於如何解決這個問題的線索?

extension Sequence where Iterator.Element == [String: Equatable] { 
    public func removeDoubles(byKey uniqueKey: String) -> [Iterator.Element] { 
     var uniqueValues: [Iterator.Element.Value] = [] 
     var noDoubles: [Iterator.Element] = [] 
     for item in self { 
      if let itemValue = item[uniqueKey] { 
       if (uniqueValues.contains { element in 
        return itemValue == element 
       }) { 
        uniqueValues.append(itemValue) 
        noDoubles.append(item) 
       } 
      } 
     } 
     return noDoubles 
    } 
} 

回答

0

[String: Equatable]是串到任何 Equatable類型的映射。沒有承諾每個值都是相同的等值類型。也就是說,創建這樣的字典實際上是不可能的(因爲Equatable有一個關聯的類型),所以這個擴展名不適用於Swift中的任何實際類型。 (您在這裏沒有收到錯誤的事實是IMO在編譯器中的一個錯誤。)

您需要使這項工作的功能是SE-0142,它被接受但未實現。您目前無法通過這種方式限制基於類型約束的擴展。

有很多方法可以實現你想要做的事情。一個簡單的方法是通過你的平等功能:

extension Sequence { 
    public func removeDoubles(with equal: (Iterator.Element, Iterator.Element) -> Bool) -> [Iterator.Element] { 
     var noDoubles: [Iterator.Element] = [] 
     for item in self { 
      if !noDoubles.contains(where: { equal($0, item) }) { 
       noDoubles.append(item) 
      } 
     } 
     return noDoubles 
    } 
} 

let noDupes = dict.removeDoubles(with: { $0["name"] == $1["name"] }) 

這比當name缺少它如何表現你的代碼略有不同,但輕微的調整可以得到你想要的東西。

也就是說,這個需求強烈地暗示了一個不正確的數據模型。如果你有這個序列的字典,並且你正在試圖構建一個擴展,那麼你幾乎肯定意味着要有一系列的結構。然後這變得更直接。字典的要點是鍵與值的任意映射。如果你有一組合法的已知鍵,那真是一個結構。

+0

不知道SE-0142如何幫助這裏,我想你的意思是[參數化擴展](https://github.com/apple/swift/blob/master/docs/GenericsManifesto.md#parameterized-extensions)? :) – Hamish

+0

我的意思是參數化擴展,但我雖然SE-0142規定。可能誤讀了142. –

+0

謝謝你的幫助。問題是這些都是JSON,我需要合併來自服務器的兩個 - 本地和遠程兩個。合併後它被保存到核心數據,並且它看起來像創建另一個結構類型過多的工作,因爲這些是NSManagedObjects,所以我不能在插入它們之前使用它們。在內存環境中,將它們存儲和比較看起來對於這個簡單的目的來說太多了,所以我繼續嘗試這個擴展。 – Suryu