Actualmente tengo esta función de reduce gruesa ...
blah: [String: Any] = queryItems.reduce([String: Any]()) { (params: [String: Any], queryItem: URLQueryItem) in var output = params output[queryItem.name] = queryItem.value return output }Estoy seguro de que hay una manera mucho más simple de hacer esto, pero no puedo entender cómo funcionaría.
¿Hay una mejor manera de hacer esto?
Por "mejor" me refiero a más limpio, más corto, más elegante, etc...
Es posible usar reduce(into:_:) en lugar de reduce(_:_) . Esto le ahorra las líneas y la sobrecarga de copiar params para cada iteración:
let blah: [String: Any] = (urlComponents.queryItems ?? []).reduce(into: [:]) { params, queryItem in params[queryItem.name] = queryItem.value }Se prefiere este método sobre
reduce(_:_:)por eficiencia cuando el resultado es un tipo de copia en escritura, por ejemplo, una matriz o un diccionario.
Puede crear un diccionario a partir del nombre y el valor de cada elemento de consulta con
let items = urlComponents.queryItems ?? [] let dict = Dictionary(items.lazy.map { ($0.name, $0.value as Any) }, uniquingKeysWith: { $1 }) En el caso de un nombre duplicado, el último valor gana (esto se puede controlar con los parámetros uniquingKeysWith: .
O elimine el as Any cast para obtener un diccionario de tipo [String: String?] :
let items = urlComponents.queryItems ?? [] let dict = Dictionary(items.lazy.map { ($0.name, $0.value ) }, uniquingKeysWith: { $1 })Alternativamente
let items = urlComponents.queryItems ?? [] let dict = Dictionary(items.lazy.map { ($0.name, [$0.value] ) }, uniquingKeysWith: +) para construir un diccionario de tipo [String : [String?]] , que contenga todos los valores para cada nombre.