【问题标题】:Swift 3 - extend an Array of Dictionary<String, Any>Swift 3 - 扩展 Dictionary<String, Any> 数组
【发布时间】:2017-02-27 16:44:57
【问题描述】:

我有这个字典数组:

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 声明处标记错误:

错误:相同类型的要求使泛型参数“元素”非泛型

我应该怎么做才能修复这个错误?

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

谢谢

【问题讨论】:

    标签: arrays dictionary swift3 extend


    【解决方案1】:
    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")
    

    【讨论】:

      【解决方案2】:

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

      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")
      

      【讨论】:

        【解决方案3】:

        感谢@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")
        }
        

        最好的,

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2020-03-07
          • 2017-06-07
          • 2015-12-13
          • 2021-10-02
          • 1970-01-01
          • 2019-10-26
          • 2016-05-28
          • 1970-01-01
          相关资源
          最近更新 更多