繁体   English   中英

Swift 3 - 扩展一个Dictionary字典<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声明标记错误:

错误:相同类型的要求使泛型参数'Element'非泛型

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

for value in self使用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{ $0.key == key }.map{ $0.value })
            return result
        }
        return result.isEmpty ? nil : result
    }
}

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

并且没有减少功能:

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

    func values(of key: String) -> [Any]? {
        var result: [Any] = []
        forEach {
            result.append($0.filter{ $0.key == key }.map{ $0.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 {$0[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 = $0.filter{$0.key == key}.map{$0.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")
}

最好,

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM