Swift字典映射 - 关闭时init

时间:2016-02-10 18:29:43

标签: ios swift dictionary

我有Swift词典:

private var params = [String : AnyObject]()

这包含以下查询项:

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

我想将此词典映射到NSURLQueryItem数组。我想做到这一点" swifty":

params.map{NSURLQueryItem.init}

但是我收到了一个错误。即使我将地图更改为[String:String?]。我知道我可以做一些像这种优雅的单线。谁能告诉你怎么样?

5 个答案:

答案 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) }