Swift 3 - 扩展字典数组<String, Any>

Swift 3 - extend an Array of Dictionary<String, Any>

我有这个字典数组:

var dicts = [["key1": "value1", "key2": "value2"], ["key1": "value3", "key2": "value4"]]

我应该如何扩展 Array 才能拥有此功能:

dicts.values(of: "key1") // result: ["value1", "value3"]

我试试这个:

extension Array where Iterator.Element == [String: Any] { // ERROR!

    func values(of key: String) -> [Any]? {
        var result: [Any]?
        for value in self {
            let val = value as! Dictionary<String, Any>
            for k in val.keys {
                if k == key {
                    if result == nil {
                        result = [Any]()
                    }
                    result?.append(val[k])
                    break
                }
            }
        }
        return result
    }
}

但我总是在 extension Array 声明处标记错误:

error: same-type requirement makes generic parameter 'Element' non-generic

我应该怎么做才能解决这个错误?

for value in self迭代Array是否正确?

谢谢

extension Sequence where Iterator.Element == [String: Any] {

    func values(of key: String) -> [Any]? {
        var result: [Any] = []
        for value in self {
            let val = value 
            for (k, v) in val {
                if k == key {
                    result.append(v)
                    break
                }
            }
        }
        return result.isEmpty ? nil : result
    }
}

var dicts: [[String: Any]] = [["key1": "value1", "key2": "value2"], ["key1": "value3", "key2": "value4"]]
dicts.values(of: "key1")   // ["value1", "value3"]

或更短的版本:

extension Sequence where Iterator.Element == [String: Any] {

    func values(of key: String) -> [Any]? {
        let result: [Any] = reduce([]) { (result, dict) -> [Any] in
            var result = result
            result.append(dict.filter{ [=11=].key == key }.map{ [=11=].value })
            return result
        }
        return result.isEmpty ? nil : result
    }
}

var dicts: [[String: Any]] = [["key1": "value1", "key2": "value2"], ["key1": "value3", "key2": "value4"]]
dicts.values(of: "key1")

并且没有 reduce 功能:

extension Sequence where Iterator.Element == [String: Any] {

    func values(of key: String) -> [Any]? {
        var result: [Any] = []
        forEach {
            result.append([=12=].filter{ [=12=].key == key }.map{ [=12=].value })
        }
        return result.isEmpty ? nil : result
    }
}

var dicts: [[String: Any]] = [["key1": "value1", "key2": "value2"], ["key1": "value3", "key2": "value4"]]
dicts.values(of: "key1")

使用 compactMap(Swift 3 中的 flatMap)的合并解决方案,过滤 nil

let dicts : [[String:Any]] = [["key1": "value1", "key2": "value2"], ["key1": "value3", "key2": "value4"]]

extension Sequence where Iterator.Element == [String:Any] {

  func values(of key: String) -> [Any] {
    return self.compactMap {[=10=][key]}
  }
}

dicts.values(of:"key1")

谢谢@JMI,你的解决方案非常优雅。

我想为您的工作添加更多细节:

extension Sequence where Iterator.Element == [String: Any] {
    func values(of key: String) -> [Any]? {
        var result = [Any]()
        forEach {
            let tmp = [=10=].filter{[=10=].key == key}.map{[=10=].value}
            if tmp.count > 0 {
                result.append(tmp[0])
            }
        }
        return result.isEmpty ? nil : result
    }
}

var dicts: [[String: Any]] = [["key1": "value1", "key2": "value2"], ["key1": "value3", "key2": "value4"]]

if let result = dicts.values(of: "key1") {
    for element in result {
        print("\(element) -> \(type(of: element))")
    }
}
else {
    print("no result")
}

最佳,