简体   繁体   English

Swift - 从日期数组创建连续日期 arrays

[英]Swift - Create consecutive date arrays from array of dates

So I have an array of Date objects, for example:所以我有一个Date对象数组,例如:

[2020-09-07 00:00:00 +0000, 2020-09-14 00:00:00 +0000, 2020-09-15 00:00:00 +0000, 2020-09-16 00:00:00 +0000, 2020-09-23 00:00:00 +0000, 2020-10-12 00:00:00 +0000, 2020-10-13 00:00:00 +0000, 2020-10-14 00:00:00 +0000, 2020-10-15 00:00:00 +0000, 2020-10-16 00:00:00 +0000]

I have to split up this array into multiple arrays containing consecutive date ranges.我必须将此数组拆分为多个包含连续日期范围的 arrays。 The result should be like this:结果应该是这样的:

[2020-09-07 00:00:00 +0000],
[2020-09-14 00:00:00 +0000, 2020-09-15 00:00:00 +0000, 2020-09-16 00:00:00 +0000], 
[2020-09-23 00:00:00 +0000], 
[2020-10-12 00:00:00 +0000, 2020-10-13 00:00:00 +0000, 2020-10-14 00:00:00 +0000, 2020-10-15 00:00:00 +0000, 2020-10-16 00:00:00 +0000]

What is the best way to achieve this in Swift?在 Swift 中实现此目标的最佳方法是什么?

You can create some helpers to get a time insensitive date and the date after a date to compare your dates for equality as shown in this post and group the dates as shown in this post :您可以创建一些助手来获取时间不敏感的日期和日期之后的日期,以比较您日期是否相等,如本文所示,并将日期分组,如本文所示:

extension Date {
    var dayAfter: Date { Calendar.current.date(byAdding: .day, value: 1, to: noon)! }
    var noon: Date { Calendar.current.date(bySettingHour: 12, minute: 0, second: 0, of: self)! }
}

extension Collection where Element == Date {
    var grouped: [[Element]] {
        return reduce(into: []) {
            $0.last?.last?.dayAfter == $1.noon ?
            $0[$0.index(before: $0.endIndex)].append($1) :
            $0.append([$1])
        }
    }
}

extension Formatter {
    static let iso8601: DateFormatter = {
        let formatter = DateFormatter()
        formatter.locale = Locale(identifier: "en_US_POSIX")
        formatter.dateFormat = "yyyy-MM-dd HH:mm:ss Z"
        formatter.timeZone = TimeZone.init(secondsFromGMT: 0)!
        return formatter
    }()
}

let arr = ["2020-09-07 00:00:00 +0000", "2020-09-14 00:00:00 +0000", "2020-09-15 00:00:00 +0000", "2020-09-16 00:00:00 +0000", "2020-09-23 00:00:00 +0000", "2020-10-12 00:00:00 +0000", "2020-10-13 00:00:00 +0000", "2020-10-14 00:00:00 +0000", "2020-10-15 00:00:00 +0000", "2020-10-16 00:00:00 +0000"]
let dates = arr.compactMap(Formatter.iso8601.date)
let grouped = dates.grouped
print(grouped)  // [[2020-09-07 00:00:00 +0000], [2020-09-14 00:00:00 +0000, 2020-09-15 00:00:00 +0000, 2020-09-16 00:00:00 +0000], [2020-09-23 00:00:00 +0000], [2020-10-12 00:00:00 +0000, 2020-10-13 00:00:00 +0000, 2020-10-14 00:00:00 +0000, 2020-10-15 00:00:00 +0000, 2020-10-16 00:00:00 +0000]]

 // to convert the dates back to strings:
 let dateStrings = grouped.map { $0.map(Formatter.iso8601.string) }
 print(dateStrings)  // [["2020-09-07 00:00:00 +0000"], ["2020-09-14 00:00:00 +0000", "2020-09-15 00:00:00 +0000", "2020-09-16 00:00:00 +0000"], ["2020-09-23 00:00:00 +0000"], ["2020-10-12 00:00:00 +0000", "2020-10-13 00:00:00 +0000", "2020-10-14 00:00:00 +0000", "2020-10-15 00:00:00 +0000", "2020-10-16 00:00:00 +0000"]]

Let's assume your String array is,假设您的String数组是,

let arr = ["2020-09-07 00:00:00 +0000", "2020-09-14 00:00:00 +0000", "2020-09-15 00:00:00 +0000", "2020-09-16 00:00:00 +0000", "2020-09-23 00:00:00 +0000", "2020-10-12 00:00:00 +0000", "2020-10-13 00:00:00 +0000", "2020-10-14 00:00:00 +0000", "2020-10-15 00:00:00 +0000", "2020-10-16 00:00:00 +0000"]

1. Get dateArr of type [Date] using are , 1.使用are获取[Date]类型的dateArr

let formatter = DateFormatter()
formatter.locale = Locale(identifier: "en_US_POSIX")
formatter.dateFormat = "yyyy-MM-dd HH:mm:ss Z"
let dateArr = arr.compactMap { formatter.date(from: $0) }

2. Sort the dateArr in ascending order, 2.dateArr按升序排序,

let sortedDateArr = dateArr.sorted { $0.compare($1) == .orderedAscending }

3. You can now split up the sortedDateArr like so, 3.您现在可以像这样拆分sortedDateArr

var result = [[String]]()
var tempArr = [String]()
for (index, date) in sortedDateArr.enumerated() {
    tempArr.append(formatter.string(from: date))
    if index+1 < sortedDateArr.count {
        if let days = Calendar.current.dateComponents([.day], from: date, to: sortedDateArr[index+1]).day, days > 1 {
            result.append(tempArr)
            tempArr = []
        }
    } else {
        result.append(tempArr)
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM