我有Swift词典:
private var params = [String : AnyObject]()
这包含以下查询项:
"lat" = "40"
"lon" = "100"
我想将此词典映射到NSURLQueryItem
数组。我想做到这一点" swifty":
params.map{NSURLQueryItem.init}
但是我收到了一个错误。即使我将地图更改为[String:String?]
。我知道我可以做一些像这种优雅的单线。谁能告诉你怎么样?
答案 0 :(得分:5)
您只需要向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)
答案 1 :(得分:3)
你对字典的价值是否必须是可选的?在字典中,当您将其键指定为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}]
我希望这会有所帮助
答案 2 :(得分:2)
你可以创建一个这样的表达式:
(1...100).map(String.init)
该类必须支持它,String
有一个具有以下签名的初始值设定项:
public init(stringInterpolationSegment expr: Int)
允许您使用String.init
作为Int -> String
。
但是在你的情况下,NSURLQueryItem
没有所需的初始值设定项,因此你可以越接近使用map
,就像传统方式一样,并将参数传递给init
这样的课程NSURLQueryItem
就像这样:
let listMapped = params.map { NSURLQueryItem(name: $0.0, value: $0.1 as? String) }
我希望这对你有所帮助。
答案 3 :(得分:0)
我看了What's the cleanest way of applying map() to a dictionary in 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)元组
答案 4 :(得分:0)
首先,你为地图功能提供的块或关闭是不是很正确。块基本上是无名函数,它们需要一些参数并返回某些类型。如果我们要详细,解决方案看起来像这样:
params.map { (a: (String, String)) -> NSURLQueryItem in
return NSURLQueryItem(name: a.0, value: a.1)
}
但是我们可以简化这段代码。字典为[String : String]
,因此可以推断地图函数将(String, String)
作为参数,因此我们不需要明确地编写该字典。
Swift还允许$n
引用元组参数的第n个元素。由于我们只有1个参数,$0
将引用第一个参数的第一个元素。
也可以推断块的返回类型,因为我们正在创建NSURLQueryItem
,这意味着我们也不需要指定它。这意味着我们也不需要在块中编写return
,我们可以创建对象。
最后,您不应该致电NSURLQueryItem.init()
来创建新的NSURLQueryItem
,而应该只是说NSURLQueryItem()
。
这是最小的解决方案:
params.map { NSURLQueryItem(name: $0, value: $1) }