Сократить `[URLQueryItem]` в `[String: Any]` - PullRequest
0 голосов
/ 27 февраля 2019

В настоящее время у меня есть эта короткая 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 голосов
/ 27 февраля 2019

Вы можете создать словарь из имени и значения каждого элемента запроса с помощью

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?]], удерживая все значения для каждого имени.

0 голосов
/ 27 февраля 2019

Можно использовать reduce(into:_:) вместо reduce(_:_).Это сэкономит вам строки и затраты на копирование params для каждой итерации:

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

Этот метод предпочтительнее, чем reduce(_:_:), для эффективности, когда результатом является копирование при записи.введите, например, массив или словарь.

...