Swift 如何在过滤数组时安全地解包可选的 属性?
Swift How could I safely unwrap an optional property when filtering an array?
我正在尝试使用对象的 class 的可选 属性 来过滤对象数组,所以我想知道安全解包此 属性 的最佳方法是什么而不用提供默认值。 属性 是 Date 类型,因此提供替代值感觉就像是 hack,但我不确定如何做得更好。我知道如何使用 guard 安全地解包常规可选,但我不确定在过滤数组时如何使用它。我的代码是这样的:
let completedGoalsThisWeek = goals.filter { [=12=].returnWeek(date: [=12=].dateAchieved) == deviceWeek }.count
问题中的 属性 是 dateAchieved,在很多情况下它会是 nil。
谢谢。
此处出错
[=10=].returnWeek(date: [=10=].dateAchieved) == deviceWeek
可以通过使参数 date
成为可选值来解决,这将使 return 也成为可选值,但它会通过,因为您可以将可选值与非值
进行比较
returnWeek
会像
func returnWeek(date:Date?) -> TypeOFWeek? {
guard let res = date else { return nil }
// here return valid result
}
或
let completedGoalsThisWeek = goals.filter { [=12=].dateAchieved != nil ? ( [=12=].returnWeek(date: [=12=].dateAchieved!) == deviceWeek ) : false }.count
或者更好的模型
class Model {
var toWeek: TypeOfWeek? {
// do where what in function which uses dateAchieved
}
}
let completedGoalsThisWeek = goals.filter { [=13=].toWeek == deviceWeek }.count
没什么特别的。就像在任何其他情况下一样打开可选的:
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
你 可以 使用 Optional.map
来缩短它,但我建议不要这样做,它太神秘了:
let completedGoalsThisWeek = goals
.lazy
.filter { goal
goal.dateAchieved.map { goal.returnWeek(date: [=11=]) == deviceWeek } ?? false
}.count
在任何一种情况下,我建议您使用 .lazy.filter
,以防止中间分配保存元素数组,如果您最终只打算对它们进行计数并立即丢弃它们的话。
我正在尝试使用对象的 class 的可选 属性 来过滤对象数组,所以我想知道安全解包此 属性 的最佳方法是什么而不用提供默认值。 属性 是 Date 类型,因此提供替代值感觉就像是 hack,但我不确定如何做得更好。我知道如何使用 guard 安全地解包常规可选,但我不确定在过滤数组时如何使用它。我的代码是这样的:
let completedGoalsThisWeek = goals.filter { [=12=].returnWeek(date: [=12=].dateAchieved) == deviceWeek }.count
问题中的 属性 是 dateAchieved,在很多情况下它会是 nil。
谢谢。
此处出错
[=10=].returnWeek(date: [=10=].dateAchieved) == deviceWeek
可以通过使参数 date
成为可选值来解决,这将使 return 也成为可选值,但它会通过,因为您可以将可选值与非值
returnWeek
会像
func returnWeek(date:Date?) -> TypeOFWeek? {
guard let res = date else { return nil }
// here return valid result
}
或
let completedGoalsThisWeek = goals.filter { [=12=].dateAchieved != nil ? ( [=12=].returnWeek(date: [=12=].dateAchieved!) == deviceWeek ) : false }.count
或者更好的模型
class Model {
var toWeek: TypeOfWeek? {
// do where what in function which uses dateAchieved
}
}
let completedGoalsThisWeek = goals.filter { [=13=].toWeek == deviceWeek }.count
没什么特别的。就像在任何其他情况下一样打开可选的:
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
你 可以 使用 Optional.map
来缩短它,但我建议不要这样做,它太神秘了:
let completedGoalsThisWeek = goals
.lazy
.filter { goal
goal.dateAchieved.map { goal.returnWeek(date: [=11=]) == deviceWeek } ?? false
}.count
在任何一种情况下,我建议您使用 .lazy.filter
,以防止中间分配保存元素数组,如果您最终只打算对它们进行计数并立即丢弃它们的话。