In an article about UserDefaults in iOS development, I saw a code snippet where flatMap is chained to UserDefaults.standard.data like below:
self.isReadStatuses = UserDefaults.standard.data(forKey: "isReadStatuses")
.flatMap { try? JSONDecoder().decode([URL: Bool].self, from: $0) } ?? [:]
Does anyone know Why can we use.flatMap here?
Because UserDefaults.standard.data(forKey:)
returns Data?
- an Optional<Data>
, and Optional
has a .flatMap
method .
Specifically here, the flatMap
closure gets a non-optional Data
, and attempts to decode it returning another [URL:Bool]?
(also, an optional because of try?
).
I can guess why are you confused, although im not sure. I think you think that .map
(and it's brothers, .flatMap
and .compactMap
) can only be used on Collections (eg an Array). That is completely wrong. .map
(and the other 2) have a meaning of transformation , not iterating through an collection/array. So while they can be used on arrays, they have many more use-cases as well.
You can read more about differences between those 3 kinds of map
here .
In the code you showed, the author of that blog post has used .flatMap
with intention of transforming an Optional<Data>
value (aka Data?) to [URL: Bool]
which is the value he wants.
let udData = UserDefaults.standard.data(forKey: "isReadStatuses")
// Short way:
let isReadStatuses1 = udData.flatMap {
try? JSONDecoder().decode([URL: Bool].self, from: $0)
} ?? [:]
// Long way:
let isReadStatuses2: [URL: Bool]
if let data = udData {
isReadStatuses2 = (try? JSONDecoder().decode([URL: Bool].self, from: data)) ?? [:]
} else {
isReadStatuses2 = [:]
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.