Swift字典映射 – 封闭中的init

我有斯威夫特字典:

private var params = [String : AnyObject]() 

这包含查询项目,如:

  • "lat" = "40"
  • "lon" = "100"

我想将这个字典映射到NSURLQueryItem数组。 我想把它变成“swifty”:

 params.map{NSURLQueryItem.init} 

但是我得到一个错误。 即使我将地图更改为[String:String?] 。 我知道我可以做这样的优雅的单行。 任何人都可以告诉如何?

你的字典价值是否需要是可选的? 在字典中,当您将其键分配为零时,该条目将被删除。

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

我build议使用非可选值字典。 我已经成功地编写了下面的代码:

 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}] 

我希望这有帮助

你只需要添加一个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) 

你可以创build一个这样的expression式:

 (1...100).map(String.init) 

该类必须支持它, String有一个具有以下签名的初始化程序:

 public init(stringInterpolationSegment expr: Int) 

允许它使用String.initInt -> String

但在你的情况下, NSURLQueryItem没有所需的初始化程序,所以你可以做的更接近像传统方式使用map ,并将parameter passing到NSURLQueryItem类的init ,就像这样:

 let listMapped = params.map { NSURLQueryItem(name: $0.0, value: $0.1 as? String) } 

我希望这可以帮助你。

我看了一下在Swift中将map()应用于字典的最简洁的方法是什么? 并提出了这两个答案:

 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)元组

首先,你提供给map函数的block或者闭包是不正确的。 块基本上是无名的函数,他们需要一些参数,并返回一些types。 如果我们要冗长的话,一个解决scheme看起来像这样:

 params.map { (a: (String, String)) -> NSURLQueryItem in return NSURLQueryItem(name: a.0, value: a.1) } 

但是我们可以简化这一点的代码。 字典是[String : String]所以可以推断map函数将一个参数(String, String)作为参数,所以我们不需要明确写出。

Swift也允许$n引用tuple参数的第n个元素。 由于我们只有1个参数, $0将引用第一个参数的第一个元素。

块的返回types也可以推断出来,因为我们正在创build一个NSURLQueryItem ,这意味着我们不需要指定。 这意味着我们也不需要在块中写入return ,我们可以创build这个对象。

最后,你不应该调用NSURLQueryItem.init()来创build一个新的NSURLQueryItem ,而应该只是说NSURLQueryItem()

这是最小的解决scheme:

 params.map { NSURLQueryItem(name: $0, value: $1) }