日付に従ってグループ化する必要があります。来る応答はソートされた形式です。グループに日付にフィルターを適用する必要があります。バックエンドからの応答:
[
{
"date": "date1"
},
{
"date": "date1"
},
{
"date": "date1"
},
{
"date": "date2"
},
{
"date": "date2"
},
{
"date": "date3"
}
]
必須:
[
[
"date": "2017-05-30T12:40:39.000Z",
"message": [
{
"date_time": 2017-05-30T12: 40: 39.000Z
}
]
],
[
"date": "2017-05-31T05:43:17.000Z",
"message": [
{
"date_time": 2017-05-31T05: 43: 17.000Z
},
{
"date_time": 2017-05-31T05: 44: 15.000Z
},
{
"date_time": 2017-05-31T05: 44: 38.000Z
}
]
]
]
複数の回答を確認しましたが、適切な解決策を見つけることができませんでした。
これは、日付(日、月、年のみ)でグループ化するための私のソリューションです。
let groupDic = Dictionary(grouping: arr) { (pendingCamera) -> DateComponents in
let date = Calendar.current.dateComponents([.day, .year, .month], from: (pendingCamera.date)!)
return date
}
このようにflatMap
とfilter
を使用して、配列を辞書にグループ化できます。
let datesArray = yourArray.flatMap { $0["date"] as? String } // return array of date
var dic = [String:[[String:Any]]]() // Your required result
datesArray.forEach {
let dateKey = $0
let filterArray = yourArray.filter { $0["date"] as? String == dateKey }
dic[$0] = filterArray
}
print(dic)
注:辞書に順序がないことを確認してください。date
の印刷順序が変更される可能性があります。
ありがとう ElegyD 。これは私のために働いています。
extension Sequence {
func groupSort(ascending: Bool = true, byDate dateKey: (Iterator.Element) -> Date) -> [[Iterator.Element]] {
var categories: [[Iterator.Element]] = []
for element in self {
let key = dateKey(element)
guard let dayIndex = categories.index(where: { $0.contains(where: { Calendar.current.isDate(dateKey($0), inSameDayAs: key) }) }) else {
guard let nextIndex = categories.index(where: { $0.contains(where: { dateKey($0).compare(key) == (ascending ? .orderedDescending : .orderedAscending) }) }) else {
categories.append([element])
continue
}
categories.insert([element], at: nextIndex)
continue
}
guard let nextIndex = categories[dayIndex].index(where: { dateKey($0).compare(key) == (ascending ? .orderedDescending : .orderedAscending) }) else {
categories[dayIndex].append(element)
continue
}
categories[dayIndex].insert(element, at: nextIndex)
}
return categories
}
}
使用法:
class Model {
let date: Date!
let anotherProperty: String!
init(date: Date, _ anotherProperty: String) {
self.date = date
self.anotherProperty = anotherProperty
}
}
let modelArray = [
Model(date: Date(), anotherProperty: "Original Date"),
Model(date: Date().addingTimeInterval(86400), anotherProperty: "+1 day"),
Model(date: Date().addingTimeInterval(172800), anotherProperty: "+2 days"),
Model(date: Date().addingTimeInterval(86401), anotherProperty: "+1 day & +1 second"),
Model(date: Date().addingTimeInterval(172801), anotherProperty: "+2 days & +1 second"),
Model(date: Date().addingTimeInterval(86400), anotherProperty: "+1 day"),
Model(date: Date().addingTimeInterval(172800), anotherProperty: "+2 days")
]
let groupSorted = modelArray.groupSort(byDate: { $0.date })
print(groupSorted) // [["Original Date"], ["+1 day", "+1 day", "+1 day & +1 second"], ["+2 days", "+2 days", "+2 days & +1 second"]]
let groupSortedDesc = modelArray.groupSort(ascending: false, byDate: { $0.date })
print(groupSortedDesc) // [["+2 days & +1 second", "+2 days", "+2 days"], ["+1 day & +1 second", "+1 day", "+1 day"], ["Original Date"]]
これがSwift 3の答えです。ここで、dateList()
は、日付でソートされたアイテムリストを持つ関数です-descending
およびguard var lastDate = sortedDates.first
最初のアイテムから日付を取得する必要があります。
func datesListGroupedByDay(sortedDates: [Date]) -> [[Date]] {
guard !sortedDates.isEmpty,
var lastDate = sortedDates.first? else { return [] }
let calendar = NSCalendar.current
var lastGroup: [Date] = []
var groups: [[Date]] = []
sortedDates.forEach { date in
guard let currentDate = date,
let currentDateDayBegin = currentDate.dateAtBeginningOfDay(),
let lastDateDayBegin = lastDate.dateAtBeginningOfDay() else { return }
let difference = calendar.dateComponents([.year, .month, .day],
from: currentDateDayBegin,
to: lastDateDayBegin)
guard let differenceYear = difference.year,
let differenceMonth = difference.month,
let differenceDay = difference.day else { return }
if differenceYear > 0 || differenceMonth > 0 || differenceDay > 0 {
lastDate = currentDate
groups.append(lastGroup)
lastGroup.removeAll()
}
lastGroup.append(date)
}
groups.append(lastGroup)
return groups
}
extension Date {
func dateAtBeginningOfDay() -> Date? {
var calendar = Calendar.current
// Or whatever you need
// if server returns date in UTC better to use UTC too
let timeZone = NSTimeZone.system
calendar.timeZone = timeZone
// Selectively convert the date components (year, month, day) of the input date
var dateComps = calendar.dateComponents([.year, .month, .day], from: self)
// Set the time components manually
dateComps.hour = 0
dateComps.minute = 0
dateComps.second = 0
// Convert back
let beginningOfDay = calendar.date(from: dateComps)
return beginningOfDay
}
}