У меня есть массив Person
объекты:
class Person {
let name:String
let position:Int
}
и массив:
let myArray = [p1,p1,p3]
Я хочу отобразиться myArray
быть Словарем [position:name]
классическое решение:
var myDictionary = [Int:String]()
for person in myArray {
myDictionary[person.position] = person.name
}
есть ли любой изящный способ Swift сделать это с функциональным подходом map
, flatMap
... или другой современный стиль Swift
Возможно, что-то вроде этого?
myArray.forEach({ myDictionary[[110].position] = [110].name })
extension Array {
func mapToDict<T>(by block: (Element) -> T ) -> [T: Element] where T: Hashable {
var map = [T: Element]()
self.forEach{ map[block([110])] = [110] }
return map
}
}
Как насчет основанного на KeyPath решения?
extension Array {
func dictionary<Key, Value>(withKey key: KeyPath<Element, Key>, value: KeyPath<Element, Value>) -> [Key: Value] {
return reduce(into: [:]) { dictionary, element in
let key = element[keyPath: key]
let value = element[keyPath: value]
dictionary[key] = value
}
}
}
Это - то, как Вы будете, использовал его:
struct HTTPHeader {
let field: String, value: String
}
let headers = [
HTTPHeader(field: "Accept", value: "application/json"),
HTTPHeader(field: "User-Agent", value: "Safari"),
]
let allHTTPHeaderFields = headers.dictionary(withKey: \.field, value: \.value)
// allHTTPHeaderFields == ["Accept": "application/json", "User-Agent": "Safari"]