如何在swift中按日期分组对象数组?

问题描述:

需要根据日期进行分组。响应以格式排序。需要在日期上应用过滤器进行分组。 响应从后端来:如何在swift中按日期分组对象数组?

[ 
    { 
    "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 
      } 
     ] 
    ] 
] 

我检查了多个答案,但没能找到一个很好的解决方案。

+0

如何分组对象?基于什么逻辑? – PGDev

+0

到目前为止发布您的解决方案。 –

您可以使用flatMapfilter这样将您的数组分组到字典中。

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威力印刷的顺序改变。

+0

它适合你吗?你有没有试过解决方案? –

+0

[ [ “日期”: “2017-05-30T12:40:39.000Z”, “消息”:[ [ “DATE_TIME”:2017-05-30T12:40:39.000Z ] ] ], [ “日期”: “2017-05-31T05:43:17.000Z”, “消息”:[ [ “DATE_TIME”:2017-05-31T05:43:17.000Z ], [ “date_time”:2017-05-31T05:44:15.000Z ] ] ] ] 我可以t o实现这样的事情。没有使用你的代码。 –

+0

@SahilJaidka你能解释一下你的意思吗,还可以编辑你的问题,而不是在评论中添加'JSON' –

这里是答案迅速3,其中dateList()是FUNC与按日期排序的项目列表 - 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 
    } 
}