我有一组日期对象 - 帖子。而我正在整理一个月。对于每一天,我想检查数组中的某个日期是否在同一天。到目前为止,我有这个:
var date = month?.startOfMonth()
var end = month?.endOfMonth()
while date! <= end! {
if posts.reduce(false,{Calendar.current.isDate(date, inSameDayAsDate: post.timeStamp)}) == true {
....
}
date = Calendar.current.date(byAdding: .day, value: 1, to: date!)
}
我认为这是从假的开始,并且在帖子中的每一天它检查它是否在同一天,如果是,它将结果变为真。但是我认为它在下次遇到假值时也会将其更改为假...
如果帖子中的任何日期与某一天相同而不是最后一天,我想要的是返回true。我怎样才能做到这一点?
答案 0 :(得分:3)
我现在的代码基本上没问题,但我会用reduce
替换contains
。
if let start = month?.startOfMonth(), let end = month?.endOfMonth() {
var date = start
var found = false
while !found && date <= end {
if posts.contains { Calendar.current.isDate(date, inSameDayAs: $0.timeStamp) } {
found = true
}
date = Calendar.current.date(byAdding: .day, value: 1, to: date)
}
if found {
// We have a match
}
}
答案 1 :(得分:1)
[已更新] 正如已经正确提到的那样,您可能更感兴趣的是拥有至少有一个帖子的Set
天,例如:
let dayComponents: Set<Calendar.Component> = [.day, .month, .year, .era]
let calendar = Calendar.current
let daysWithPosts = Set(posts.map { post in
calendar.dateComponents(dayComponents, from: post.date)
})
然后对于每个date
,你可以检查它是否在该集合中(上下文不变,请注意力量展开):
while date! <= end! {
let currentDayComponents = calendar.dateComponents(dayComponents, from: date)
let postsFound = daysWithPosts.contains(currentDayComponents)
// <use postsFound as needed>
date = Calendar.current.date(byAdding: .day, value: 1, to: date!)
}
原始答案,适用于多个日期:
这应该告诉我们某天是否有帖子:
func areTherePosts(in posts: [Post], fromSameDayAs date: Date) -> Bool {
let calendar = Calendar.current
let dayComponents: Set<Calendar.Component> = [.day, .month, .year, .era]
let specificDateComponents = calendar.dateComponents(dayComponents, from: date)
return posts.contains { post in
calendar.dateComponents(dayComponents, from: post.date) == specificDateComponents
}
}
在您的上下文中使用(再次,未更改):
while date! <= end! {
let postsFound = areTherePosts(in: posts, fromSameDayAs: date!)
// <use postsFound as needed>
date = Calendar.current.date(byAdding: .day, value: 1, to: date!)
}
答案 2 :(得分:1)
我基本上构建了一个堆栈视图 - 每天 - 我创建一个矩形,如果当天有帖子则为蓝色,如果没有则清除。因此,我可能需要知道这一天。但是,过滤数组中指定月份的元素似乎很有趣。你能说明怎么做吗?也许我可以指定那些日子的位置,然后使用insertItem atIndex
填充其余的stackArray值
基本上,我可以从两个函数开始,一个用于按月过滤日期,另一个按日过滤。我会这样做的原因,在你的情况下,你是每天,你不想重新过滤本月的所有可用日期(但那只是我)
func dates(_ dates: [Date], withinMonth month: Int) -> [Date] {
let calendar = Calendar.current
let components: Set<Calendar.Component> = [.month]
let filtered = dates.filter { (date) -> Bool in
calendar.dateComponents(components, from: date).month == month
}
return filtered
}
func dates(_ dates: [Date], forDay day: Int) -> [Date] {
let calendar = Calendar.current
let components: Set<Calendar.Component> = [.day]
let filtered = dates.filter { (date) -> Bool in
calendar.dateComponents(components, from: date).day == day
}
return filtered
}
您可以使用contains
方法,同时匹配月和日,但同样需要考虑开销。在上面的示例中,您只需检查日期是否包含在按月生成的过滤日期中,这可能更接近您所需的结果
nb 这不像first
或contains
那样有效,因为这会迭代整个数组找到每个匹配的元素,但是,它有很好的副作用为您提供更多信息。例如,您可以对生成的过滤器进行排序,并简单地从月末开始迭代到最后,在每个匹配日出现时弹出,作为一个想法
另一种方法可能是按月过滤可用日期,如上所述,然后将结果映射到Set
天(即Int
),这将允许您迭代在每个月的每一天,使用contains(day)
执行简单的检查,看看是否包含该日。
同样,您可以将视图映射到每一天并迭代Set
,从而更改每个视图的状态。
这一切都取决于更多的上下文然后可用,但不用说,有很多方法可以解决这个问题