繁体   English   中英

Swift字典映射 - 关闭时init

[英]Swift dictionary map - init in closure

我有Swift词典:

private var params = [String : AnyObject]()

这包含以下查询项:

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

我想将这个字典映射到NSURLQueryItem数组。 我想让它变得“很棒”:

params.map{NSURLQueryItem.init}

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

你只需要添加一个failable initializerNSURLQueryItem接收这样一个元组(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一样,并将参数传递给类NSURLQueryIteminit ,就像这样:

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM