Reputation: 12687
I'm doing this,
let x = results.compactMap {
if case .person (let P) = $0 { return P }
else { return nil }
}
x is [Person]
, obviously results is something like
enum ResultItem: Decodable {
case person(Person)
case cat(Cat)
case budgie(Budgie)
Anyway I'm doing this,
let x = results.compactMap {
if case .person (let P) = $0 { return P }
else { return nil }
}
inevitably someone on here can make me look like a fool and show a tighter way to do this in current Swift!
Go for it...
Upvotes: 0
Views: 328
Reputation: 17544
maybe define
func person(_ r: ResultItem)->Person? {
if case .person (let P) = r { return P }
else { return nil }
}
and next compact. at least it is easier to read for me ...
let persons = items.compactMap(person)
or even better
extension ResultItem {
static func person(_ r: ResultItem)->Person? {
if case .person (let P) = r { return P }
else { return nil }
}
}
and
let persons = items.compactMap(ResultItem.person)
Upvotes: 1
Reputation: 535411
So results
is an array of ResultItem and the idea is to extract the payloads from only the ones that are Persons?
I don't know if this is "tighter" but I would probably do it with for case let
:
let arr : [ResultItem] = // ...
var persons = [Person]()
for case let .person(p) in arr { persons.append(p) }
You might reasonably object: "But I don't want persons
to be a var
." Yes, I know how you feel. So sometimes I say this instead (wordier, to be sure):
let persons : [Person] =
arr.reduce(into: []) {if case let .person(p) = $1 {$0.append(p)}}
They are both really ways of saying the same thing: append only if you can extract a Person. Of course you are doing that same thing, in a way, but the roundabout return nil
into a compactMap
is probably the objectionable part, and the second formulation is arguably a one-liner, so perhaps that's "tighter".
Upvotes: 2