在swift中将字典转换为查询字符串?

时间:2017-06-30 04:15:30

标签: swift

我有一个字典为[String:Any]。现在我要转换这个词典键&价值为key=value&key=value。我创建了以下扩展程序,但它对我不起作用。

extension Dictionary {

    var queryString: String? {
        var output: String = ""
        for (key,value) in self {
            output +=  "\(key)=\(value)\(&)"
        }
        return output
    }
}

12 个答案:

答案 0 :(得分:21)

使用NSURLQueryItem

  

NSURLQueryItem对象表示一个名称/值对   URL的查询部分中的项目。您使用查询项目   NSURLComponents对象的queryItems属性。

要创建一个,请使用指定的初始值设定项queryItemWithName:value:,然后将其添加到NSURLComponents以生成NSURL。例如:

<强>目的-C:

NSDictionary *queryDictionary = @{ @"q": @"ios", @"count": @"10" };
NSMutableArray *queryItems = [NSMutableArray array];
for (NSString *key in queryDictionary) {
    [queryItems addObject:[NSURLQueryItem queryItemWithName:key value:queryDictionary[key]]];
}
components.queryItems = queryItems;
NSURL *url = components.URL; // http://stackoverflow.com?q=ios&count=10

<强>夫特:

let queryDictionary = [ "q": "ios", "count": "10" ]
var components = URLComponents()
components.queryItems = queryDictionary.map {
     URLQueryItem(name: $0, value: $1)
}
let URL = components.url

答案 1 :(得分:15)

另一种Swift-esque方法:

let params = [
    "id": 2,
    "name": "Test"
]

let urlParams = params.flatMap({ (key, value) -> String in
    return "\(key)=\(value)"
}).joined(separator: "&")

答案 2 :(得分:2)

extension Dictionary {
    var queryString: String? {
        return self.reduce("") { "\($0!)\($1.0)=\($1.1)&" }
    }
}

答案 3 :(得分:2)

试试这个:

func queryItems(dictionary: [String:Any]) -> String {
        var components = URLComponents()
        print(components.url!)
        components.queryItems = dictionary.map {
            URLQueryItem(name: $0, value: $1)
        }
       return (components.url?.absoluteString)!
    }

答案 4 :(得分:2)

 var populatedDictionary = ["key1": "value1", "key2": "value2"]

 extension Dictionary {
     var queryString: String {
        var output: String = ""
        for (key,value) in self {
            output +=  "\(key)=\(value)&"
        }
        output = String(output.characters.dropLast())
        return output
     }
  }

输出:key1 = value1&amp; key2 = value2

希望它有所帮助。快乐编码!!

答案 5 :(得分:1)

import Foundation

    extension URL {
        var queryItemsDictionary: [String: String] {
            var queryItemsDictionary = [String: String]()

            // we replace the "+" to space and then encode space to "%20" otherwise after creating URLComponents object
            // it's not possible to distinguish the real percent from the space in the original URL
            let plusEncodedString = self.absoluteString.replacingOccurrences(of: "+", with: "%20")

            if let queryItems = URLComponents(string: plusEncodedString)?.queryItems {
                queryItems.forEach { queryItemsDictionary[$0.name] = $0.value }
            }
            return queryItemsDictionary
        }
    }

该扩展名将允许您解析同时用加号编码+符号和空格的URL,例如:

https://stackoverflow.com/?q=First+question&email=mail%2B10@mail.com

该扩展程序会将“ q”解析为“第一个问题”,将“电子邮件”解析为“ mail+10@mail.com”

答案 6 :(得分:1)

与@KKRocks相同,具有针对Swift 4.1.2的更新

func queryItems(dictionary: [String:Any]) -> String {
    var components = URLComponents()
    print(components.url!)
    components.queryItems = dictionary.map {
        URLQueryItem(name: $0, value: String(describing: $1))
    }
   return (components.url?.absoluteString)!
}

答案 7 :(得分:1)

@luckyShubhra答案的紧凑版本

Swift 5.0

SELECT ID, Name, CP, STRING_AGG(Job, ',')
FROM myTable
GROUP BY ID, Name, CP
ORDER BY ID

用法

extension Dictionary {
    var queryString: String {
        var output: String = ""
        forEach({ output += "\($0.key)=\($0.value)&" })
        output = String(output.dropLast())
        return output
    }
}

答案 8 :(得分:0)

protocol ParametersConvertible {
    func asParameters() -> [String:Any] 
}

protocol QueryStringConvertible {
    func asQuery() -> String
}

extension QueryStringConvertible where Self: ParametersConvertible {
    func asQuery() -> String {
        var queries: [URLQueryItem] = []
        for (key, value) in self.asParameters() {
            queries.append(.init(name: key, value: "\(value)"))
        }

        guard var components = URLComponents(string: "") else {
            return ""
        }

        components.queryItems = queries
        return components.percentEncodedQuery ?? ""
    }
}

答案 9 :(得分:0)

将此功能添加到您的控制器

func getQueryString(params : [String : Any])-> String{

        let urlParams = params.compactMap({ (key, value) -> String in
            return "\(key)=\(value)"
        }).joined(separator: "&")
        var urlString = "?" + urlParams
        if let url = urlString.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed){
            urlString = url
        }
          return urlString
    }

示例

self.getQueryString(params:[“ name”:“ deep ios开发人员”,“年龄”:22])

答案 10 :(得分:0)

对于任何想要“简短,简短”版本的人。

使用map压缩,您不需要forEach或for循环。协议也受约束,无法在字典上执行类型。

extension Dictionary where Key : StringProtocol, Value : StringProtocol {
    var queryString: String {
        self.map { "\($0)=\($1)" }.joined(separator: "&")
    }
}

答案 11 :(得分:0)

我写了这个助手 fn,我认为它很干净:

private static func queryStringParamsToString(_ dictionary: [String: Any]) -> String {
    return dictionary
        .map({(key, value) in "\(key)=\(value)"})
        .joined(separator: "&")
        .addingPercentEncoding(withAllowedCharacters: .urlPathAllowed)!

}