将[URLQueryItem]简化为[[String:Any]`

时间:2019-02-27 17:30:50

标签: swift reduce

目前,我已经有了这个笨拙的reduce函数...

blah: [String: Any] = queryItems.reduce([String: Any]()) {
    (params: [String: Any], queryItem: URLQueryItem) in

    var output = params

    output[queryItem.name] = queryItem.value

    return output
}

我敢肯定有一种更简单的方法可以做到这一点,但是我无法确定它是如何工作的。

是否有一种“更好”的方法?

“更好”是指更干净,更短,更优雅等……

2 个答案:

答案 0 :(得分:4)

可以使用reduce(into:_:)代替reduce(_:_)。这样既节省了代码行,又节省了每次迭代复制params的开销:

let blah: [String: Any] = (urlComponents.queryItems ?? []).reduce(into: [:]) {
    params, queryItem in 
    params[queryItem.name] = queryItem.value
}
  

当结果是写时复制类型(例如数组或字典)时,此方法优于reduce(_:_:),以提高效率。

答案 1 :(得分:2)

您可以使用每个查询项的名称和值创建一个字典

let items = urlComponents.queryItems ?? []
let dict = Dictionary(items.lazy.map { ($0.name, $0.value as Any) },
                      uniquingKeysWith: { $1 })

如果名称重复,则以更高的值为准(可以使用uniquingKeysWith:参数进行控制。)

或删除as Any类型转换以获取[String: String?]类型的字典:

let items = urlComponents.queryItems ?? []
let dict = Dictionary(items.lazy.map { ($0.name, $0.value ) },
                      uniquingKeysWith: { $1 })

或者

let items = urlComponents.queryItems ?? []
let dict = Dictionary(items.lazy.map { ($0.name, [$0.value] ) },
                      uniquingKeysWith: +)

构建[String : [String?]]类型的字典,为每个名称保存 all 个值。