[英]Swift dictionary map - init in closure
我有Swift词典:
private var params = [String : AnyObject]()
这包含以下查询项:
"lat" = "40"
"lon" = "100"
我想将这个字典映射到NSURLQueryItem
数组。 我想让它变得“很棒”:
params.map{NSURLQueryItem.init}
但是我收到了一个错误。 即使我将地图更改为[String:String?]
。 我知道我可以做一些像这种优雅的单线。 谁能说出来怎么样?
你只需要添加一个failable initializer
到NSURLQueryItem
接收这样一个元组(String, AnyObject)
extension NSURLQueryItem {
convenience init?(tuple: (String, AnyObject)) {
guard let value = tuple.1 as? String else { return nil }
self.init(name: tuple.0, value: value)
}
}
let params: [String:AnyObject] = ["lat": "40", "lon": "100"]
let queryItems = params.flatMap(NSURLQueryItem.init)
您对字典的价值是否必须是可选的? 在字典中,当您将其键指定为nil时,该条目将被删除。
var params = [String:String?]()
params["lat"] = "40"
params["lon"] = "100"
params["key"] = "hey"
print(params) //result: ["lat": Optional("40"), "lon": Optional("100"), "key": Optional("hey")]
params["key"] = nil
print(params) //result: ["lat": Optional("40"), "lon": Optional("100")]
我建议使用非可选值字典。 我已成功编写以下代码:
import UIKit
var params = [String:String]()
params["lat"] = "40"
params["lon"] = "100"
let nsurl = params.map() {NSURLQueryItem.init(name: $0, value: $1)}
print(nsurl)
//Result:
//[<NSURLQueryItem 0x7f8252d29730> {name = lat, value = 40}, <NSURLQueryItem 0x7f8252d29700> {name = lon, value = 100}]
我希望这有帮助
你可以创建一个这样的表达式:
(1...100).map(String.init)
该类必须支持它, String
有一个具有以下签名的初始化程序:
public init(stringInterpolationSegment expr: Int)
允许它使用String.init
称为Int -> String
。
但在你的情况下, NSURLQueryItem
没有所需的初始化程序,所以你可以做得越接近就像使用传统方式的map
一样,并将参数传递给类NSURLQueryItem
的init
,就像这样:
let listMapped = params.map { NSURLQueryItem(name: $0.0, value: $0.1 as? String) }
我希望这对你有帮助。
我看了一下将map()应用到Swift字典中的最简洁方法是什么? 并提出了这两个答案:
var params = ["lat": "40", "lon":"100"]
var p:[NSURLQueryItem] = []
var result1 = params.map { (key, value) in p.append(NSURLQueryItem(name:key, value:value)) } // version 1
var result2 = params.reduce([NSURLQueryItem]()) { $0 + [NSURLQueryItem(name:$1.0, value:$1.1)] } // version 2
在版本1中,map()传递的参数是(String,String)元组。 在版本2中,reduce()传递的参数是[NSURLQueryItem]和(String,String)元组
首先,您为地图功能提供的块或闭包不是很正确。 块基本上是无名函数,它们需要一些参数并返回某些类型。 如果我们是冗长的,解决方案看起来像这样:
params.map { (a: (String, String)) -> NSURLQueryItem in
return NSURLQueryItem(name: a.0, value: a.1)
}
但是我们可以简化这段代码。 字典是[String : String]
因此可以推断map函数将(String, String)
作为参数,因此我们不需要显式地编写它。
Swift还允许$n
引用元组参数的第n个元素。 由于我们只有1个参数,因此$0
将引用第一个参数的第一个元素。
也可以推断块的返回类型,因为我们正在创建NSURLQueryItem
,这意味着我们也不需要指定它。 这意味着我们也不需要在块中写入return
,我们只需创建对象即可。
最后,你不应该调用NSURLQueryItem.init()
来创建一个新的NSURLQueryItem
,你应该只是说NSURLQueryItem()
。
这是最小的解决方案:
params.map { NSURLQueryItem(name: $0, value: $1) }
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.