0

I got an dictionary which looks like:

["foo": "whatever", "this": "that", "category": ["cat1", "cat2"]] 

and I need it to be a string like:

foo=whatever&this=that&category=cat1&category=cat2 

so that if a key has values of type array, the key should occur multiple times in the string.

1

2 Answers 2

2

As Alexander suggested this is a solution with URLComponents and URLQueryItem

import Foundation let dict: [String: Any] = [ "foo": "whatever", "this": "that", "category": [ "cat1", "cat2" ] ] var queryItems = [URLQueryItem]() for (key, value) in dict { if let strings = value as? [String] { queryItems.append(contentsOf: strings.map{ URLQueryItem(name: key, value: $0) }) } else { queryItems.append(URLQueryItem(name: key, value: value as? String)) } } var urlComponents = URLComponents(string: "http://myserver.com")! urlComponents.queryItems = queryItems let url = urlComponents.url! print(url.absoluteString) // => http://myserver.com?this=that&foo=whatever&category=cat1&category=cat2 

A similar solution, but simpler, using flatMap:

let queryItems = dict.flatMap { key, value -> [URLQueryItem] in if let strings = value as? [String] { return strings.map{ URLQueryItem(name: key, value: $0) } } else { return [URLQueryItem(name: key, value: value as? String)] } } var urlComponents = URLComponents(string: "http://myserver.com")! urlComponents.queryItems = queryItems let url = urlComponents.url! print(url.absoluteString) // => http://myserver.com?this=that&foo=whatever&category=cat1&category=cat2 
Sign up to request clarification or add additional context in comments.

4 Comments

Edited to use conditional binding rather than is + as!
Should I also edit to use map over repeated appends?
@Alexander Go ahead :-)
@Alexander Thank you very much.
0

I believe something like this should work if you know your dictionary types:

var string = "" for key in dict.keys { if let array = dict[key] as? [String] { for arrayItem in array { string += "\(key)=\(arrayItem)&" } } else if let value = dict[key] as? String { string += "\(key)=\(value)&" } } print(string.substring(to: string.index(before: string.endIndex))) 

Noting that this might print them in a random order because the dictionary is not ordered

1 Comment

thanks for that. The order is irrelevant, maybe a more swifty approach, something with map or flatmap?

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.