[英]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.