Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Swift dictionary map - init in closure

I have Swift dictionary:

private var params = [String : AnyObject]()

This contains query items like:

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

I would like to map this dictionary to NSURLQueryItem array. I want to make it "swifty":

params.map{NSURLQueryItem.init}

But I get an error. Even if I change the map to be [String:String?]. I know I can do something like this elegant one-liner. Can anybody tell how?

like image 840
Prettygeek Avatar asked Sep 14 '25 18:09

Prettygeek


2 Answers

You just need to add a failable initializer to NSURLQueryItem that receives a tuple like this (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)
    }
}

That's it!

let params: [String:AnyObject] = ["lat": "40", "lon": "100"]
let queryItems = params.flatMap(NSURLQueryItem.init)
like image 93
Luca Angeletti Avatar answered Sep 16 '25 09:09

Luca Angeletti


Does your value for the dictionary need to be an optional? In a dictionary, when you assign its key as nil, the entry is deleted.

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

I suggest using a non optional-value dictionary. I have successfully written the code below:

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

I hope this helps

like image 32
Ataias Reis Avatar answered Sep 16 '25 08:09

Ataias Reis