簡體   English   中英

Swift:過濾字典

[英]Swift: filter dictionary

我正在嘗試快速過濾字典:

var data: [String: String] = [:]
data = data.filter { $0.1 == "Test" }

上面的過濾器代碼在 swift 2 下編譯,但產生以下錯誤:

無法將“[(String, String)]”類型的值分配給“[String : String]”類型的值

這是 swift 編譯器中的錯誤還是這不是在 swift 中過濾字典的正確方法?

非常感謝您提前!

這已在Swift 4中修復

let data = ["a": 0, "b": 42]
let filtered = data.filter { $0.value > 10 }
print(filtered) // ["b": 42]

在Swift 4中,過濾的字典返回字典。


Swift 2和3的原始答案

問題是data是字典但filter的結果是數組,因此錯誤消息表明您不能將后者的結果分配給前者。

您可以為結果數組創建一個新的變量/常量:

let data: [String: String] = [:]
let filtered = data.filter { $0.1 == "Test" }

這里filtered是一個元組數組: [(String, String)]

過濾后,如果您需要,可以重新創建新詞典:

var newData = [String:String]()
for result in filtered {
    newData[result.0] = result.1
}

如果您決定不使用filter ,則可以改變原始字典或其副本:

var data = ["a":"Test", "b":"nope"]
for (key, value) in data {
    if value != "Test" {
        data.removeValueForKey(key)
    }
}
print(data) // ["a": "Test"]

注意:在Swift 3中, removeValueForKey已重命名為removeValue(forKey:) ,因此在此示例中它將變為data.removeValue(forKey: key)

data.forEach { if $1 != "Test" { data[$0] = nil } }

只是另一種方法(稍微簡化)來過濾掉字典中的對象。

根據Apple文檔,過濾:

返回一個數組,該數組按順序包含滿足給定謂詞的序列元素。

https://developer.apple.com/reference/swift/sequence/1641239-filter

我發現自己需要做OP所要求的事情並最終編寫以下擴展(Swift 3):

extension Dictionary
{
  func filteredDictionary(_ isIncluded: (Key, Value) -> Bool)  -> Dictionary<Key, Value>
  {
    return self.filter(isIncluded).toDictionary(byTransforming: { $0 })
  }
}

extension Array
{
  func toDictionary<H:Hashable, T>(byTransforming transformer: (Element) -> (H, T)) -> Dictionary<H, T>
  {
    var result = Dictionary<H,T>()
    self.forEach({ element in
      let (key,value) = transformer(element)
      result[key] = value
    })
    return result
  }
}

用法:

let data = ["a":"yes", "b":"nope", "c":"oui", "d":"nyet"]
let filtered = data.filteredDictionary({ $0.1 >= "o" })

// filtered will be a dictionary containing ["a": "yes", "c": "oui"]

我發現這個方法在過濾或應用一些導致字典元素數組的其他變換后很有用:

extension Array {
    func dictionary<K: Hashable, V>() -> [K: V] where Element == Dictionary<K, V>.Element {
        var dictionary = [K: V]()
        for element in self {
            dictionary[element.key] = element.value
        }
        return dictionary
    }
}

要使用它,只需說出類似的話:

dictionary = dictionary.filter{ $0.key == "test" }.dictionary()

這種方法的優點是不需要將任何類型的參數傳遞給dictionary()方法。 通用類型參數告訴編譯器它需要知道的一切。

請檢查復雜的字典,如字典數組,希望對您有所幫助!! 謝謝你

https://stackoverflow.com/a/54402309/8201581

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM