Reputation: 2279
I am trying to filter an array of objects with an optional property of the objects' class, so I was wondering what's the best way to unwrap this property safely without providing a default value. The property is of type Date so providing an alternative value feels like a hack, but I'm not sure how to do it better. I know how to safely unwrap a regular optional with guard but I'm not sure how to use this when filtering an array. The code I have is this:
let completedGoalsThisWeek = goals.filter { $0.returnWeek(date: $0.dateAchieved) == deviceWeek }.count
The property in question is dateAchieved and it will be nil in a lot of circumstances.
Thank you.
Upvotes: 3
Views: 3835
Reputation: 100533
Error here
$0.returnWeek(date: $0.dateAchieved) == deviceWeek
can ve solved by making paramter date
an optional which will make the return optional too but it will pass as you can compare an optional value with non-one
returnWeek
Would be like
func returnWeek(date:Date?) -> TypeOFWeek? {
guard let res = date else { return nil }
// here return valid result
}
OR
let completedGoalsThisWeek = goals.filter { $0.dateAchieved != nil ? ( $0.returnWeek(date: $0.dateAchieved!) == deviceWeek ) : false }.count
Or better the model
class Model {
var toWeek: TypeOfWeek? {
// do where what in function which uses dateAchieved
}
}
let completedGoalsThisWeek = goals.filter { $0.toWeek == deviceWeek }.count
Upvotes: 2
Reputation: 63321
There's nothing special to it. Just unwrap the optional like you would in any other case:
let completedGoalsThisWeek = goals
.lazy
.filter { goal -> Bool in
guard let dateAchieved = goal.dateAchieved else { return false }
let isCurrentWeek = goal.returnWeek(date: dateAchieved) == deviceWeek
return isCurrentWeek
}.count
You could use Optional.map
to shorten this, but I would advise against it, it's too cryptic:
let completedGoalsThisWeek = goals
.lazy
.filter { goal
goal.dateAchieved.map { goal.returnWeek(date: $0) == deviceWeek } ?? false
}.count
In either case, I suggest you use .lazy.filter
, to prevent the intermediate allocation to hold an array of elements, if you're ultimately going to only count them and immediately discard them.
Upvotes: 4