[英]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.