如何对数组中的日期进行分组?

Posted

技术标签:

【中文标题】如何对数组中的日期进行分组?【英文标题】:How to group the dates from array? 【发布时间】:2020-03-28 01:54:12 【问题描述】:

我的日期格式是这样的“2019-12-03T05:58:11.317Z”。我想对相同的日期元素进行分组。我可以根据日期创建 UITableView 部分。这是数组,我有三个不同的日期,所以我想创建 3 个部分。这里的问题newArrayList 没有保存所有元素。

        NSMutableArray * arrayList;
        NSMutableArray *newArrayList;
        //This is my date array
        arrayList = [[NSMutableArray alloc] initWithObjects:@“2019-12-03T05:58:11.317Z”, @“2019-12-03T05:58:10.317Z”, @“2019-12-03T05:58:01.317Z”, @“2019-12-03T05:55:12.448Z”, @“2019-12-03T05:48:11.317Z”, @“2019-12-03T05:28:11.317Z”, @“2019-12-03T05:11:24.004Z”, @“2019-12-03T05:28:11.317Z”, @“2019-12-03T05:55:12.965Z”, @“2019-12-02T15:09:35.408Z”, @“2019-12-02T15:09:38.187Z”, @“2019-12-02T15:43:02.118Z”, @“2019-12-02T15:44:09.344Z”, @“2019-12-02T17:07:55.038Z”, @“2019-12-02T16:42:16.649Z”, @“2019-12-01T16:42:16.649Z”, nil];

        newArrayList = [[NSMutableArray alloc]init];//Here I want to same date elements 

            NSDate *fromDate;
            NSMutableArray *tempArray = [[NSMutableArray alloc] init];
            for (int i=0; i<arrayList.count; i++) 
                NSDate *dt1 = fromDate;
                NSDate *dt2 = [self getLocalDateTimeFromUTC2:[arrayList objectAtIndex:i]];
                if (i != 0) 
                    if ([self isSameDay:dt1 otherDay:dt2] == YES) 
                        [tempArray addObject:t];
                     else 
                        [newArrayList addObject:tempArray];
                    //  [tempArray removeAllObjects];
                    
                
                fromDate = dt2;
            

//To get required date formate
-(NSDate *)getLocalDateTimeFromUTC2:(NSString *)strDate


// create dateFormatter with UTC time format
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:@"yyyy-MM-dd'T'HH:mm:ss.SSSZZZZ"]; //@"yyyy-MM-dd'T'HH:mm:ss.SSSZZZZ"
[dateFormatter setTimeZone:[NSTimeZone timeZoneWithAbbreviation:@"UTC"]];
//    NSLog(@"%@", t.dateAndTime); //2019-12-02T15:09:38.187Z
NSDate *date = [dateFormatter dateFromString:strDate]; // create date from string

// change to a readable time format and change to local time zone
[dateFormatter setDateFormat:@"dd-MM-yyyy"];
[dateFormatter setTimeZone:[NSTimeZone localTimeZone]];
NSString *timestamp = [dateFormatter stringFromDate:date];

NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
[dateFormat setDateFormat:@"dd-MM-yyyy"];
[dateFormat setTimeZone:[NSTimeZone localTimeZone]];
NSDate *date2 = [dateFormat dateFromString:timestamp];
//    NSLog(@"%@", date2);

return date2;


//To compare two dates
- (BOOL)isSameDay:(NSDate*)date1 otherDay:(NSDate*)date2 

NSCalendar* calendar = [NSCalendar currentCalendar];
unsigned unitFlags = NSCalendarUnitYear | NSCalendarUnitMonth |  NSCalendarUnitDay;
NSDateComponents* comp1 = [calendar components:unitFlags fromDate:date1];
NSDateComponents* comp2 = [calendar components:unitFlags fromDate:date2];
return [comp1 day]   == [comp2 day] && [comp1 month] == [comp2 month] && [comp1 year]  == [comp2 year];

【问题讨论】:

newArrayList 只保存最后一组,我想保存所有组。 您的实际数据如何。我的意思是您想对同一组日期进行分组,但是您将在行中显示什么?日期是作为字符串数组还是在字典数组中出现? 我将在部分中显示同一天的日期,在 geader 中我将显示当天。比如通话记录。 表示在部分中显示日期,在行中显示时间? @dahiya_boy,不,在部分中,我将仅显示特定的组日期,在行中,我将一一显示所有日期和时间。 【参考方案1】:

试试这个:

NSMutableDictionary *dictByDate = [NSMutableDictionary new];
NSMutableArray *newArr = [NSMutableArray new] ;

for(NSString *strDate in arrayList)


    // convert date to proper formate (if needed)

    NSDateFormatter *format = [[NSDateFormatter alloc] init];
    [format setDateFormat:@"yyyy-MM-dd'T'HH:mm:ss.SSSZZZZ"];
    NSDate *dateNew = [format dateFromString:strDate];
    [format setDateFormat:@"MMMM-dd-yyyy"];
    NSString *finalDateString = [format stringFromDate:dateNew];

    NSLog(@"%@",finalDateString) ;

    NSMutableArray *arrWithSameDate = dictByDate[finalDateString];
    if(! arrWithSameDate)
    
        arrWithSameDate = [NSMutableArray new];
        dictByDate[finalDateString] = arrWithSameDate;
    
    [arrWithSameDate addObject: strDate];



[newArr addObjectsFromArray:[dictByDate allValues]] ;

NSLog(@"group data: %@", newArr);

【讨论】:

我可以期望从这段代码中输出类似数组的数组吗? 输出如下:[“2019 年 11 月 28 日”:[“2019 年 11 月 28 日”,“2019 年 11 月 28 日”],“2019 年 11 月 29 日”:[“2019 年 11 月 29 日”, “2019 年 11 月 29 日”、“2019 年 11 月 29 日”]、“2019 年 11 月 30 日”:[“2019 年 11 月 30 日”]] [[03-12-2019 12, 03-12-2019 12, 03-12-2019 12], [02-12-2019 12, 02-12-2019 12, 02-12 -2019 12],[01-12-2019 12]];够了【参考方案2】:

我在 swift 中做,希望你会在 obj-c 中管理


    假设您有以下数据

    let arrDates = [  "2019-12-03T05:58:11.317Z ",   "2019-12-03T05:58:10.317Z ",   "2019-12-03T05:58:01.317Z ",   "2019-12-03T05:55:12.448Z ",   "2019-12-03T05:48:11.317Z ",   "2019-12-03T05:28:11.317Z ",   "2019-12-03T05:11:24.004Z ",   "2019-12-03T05:28:11.317Z ",   "2019-12-03T05:55:12.965Z ",   "2019-12-02T15:09:35.408Z ",   "2019-12-02T15:09:38.187Z ",   "2019-12-02T15:43:02.118Z ",   "2019-12-02T15:44:09.344Z ",   "2019-12-02T17:07:55.038Z ",   "2019-12-02T16:42:16.649Z ",   "2019-12-01T16:42:16.649Z "]
    

    制作日期组

    let dictGroupDate = Dictionary(grouping: arrDates)  (strdate) -> String in
    let df = DateFormatter()
    df.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZZZZ"
    let date = df.date(from: strdate)
    df.dateFormat = "yyyy-MM-dd"
    return df.string(from: date!)
    
    

    获取所有部分日期并对其进行排序

    let arrDateKey = Array(dictGroupDate.keys).sorted  (strdate1, strdate2) -> Bool in
    let df = DateFormatter()
    df.dateFormat = "yyyy-MM-dd"
    let date1 = df.date(from: strdate1)
    let date2 = df.date(from: strdate2)
    
    return date1!.compare(date2!)  == .orderedAscending
    
    

    对每个日期的时间进行排序并创建新的字典

     var newGroupedDates = [String : [String]]()
    
    for strKey in arrDateKey 
    let sortedTime = dictGroupDate[strKey]?.sorted(by:  (strdate1, strdate2) -> Bool in
        let df = DateFormatter()
        df.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZZZZ"
        let date1 = df.date(from: strdate1)
        let date2 = df.date(from: strdate2)
    
        return date1!.compare(date2!)  == .orderedAscending
    
      )
    
    newGroupedDates[strKey] = sortedTime!
    
    

    UITABLEVIEW中显示数据

    // NumberOfSections
    arrDateKey.count
    
    //NumberOfRows
    let key = arrDateKey[indexPath.section]
    newGroupedDates[key]?.count
    
    // CellForRow
    // To get correct date and Time
    
    let key = arrDateKey[indexPath.section]
    let item = newGroupedDates[key]![indexPath.row]
     // Now item is the date string, and do whatever you wanted to do.
    

输出

最终的新分组日期

["2019-12-03": ["2019-12-03T05:11:24.004Z ", "2019-12-03T05:28:11.317Z ", "2019-12-03T05:28:11.317Z ", "2019-12-03T05:48:11.317Z ", "2019-12-03T05:55:12.448Z ", "2019-12-03T05:55:12.965Z ", "2019-12-03T05:58:01.317Z ", "2019-12-03T05:58:10.317Z ", "2019-12-03T05:58:11.317Z "], "2019-12-02": ["2019-12-02T15:09:35.408Z ", "2019-12-02T15:09:38.187Z ", "2019-12-02T15:43:02.118Z ", "2019-12-02T15:44:09.344Z ", "2019-12-02T16:42:16.649Z ", "2019-12-02T17:07:55.038Z "], "2019-12-01": ["2019-12-01T16:42:16.649Z "]]

如果我错过了什么然后评论我。

【讨论】:

你能写到objective c吗 我只想在finaldatearray中保存日期数组,这就够了。我不想要字典类型。我可以获取每个部分的第一个对象日期,并将显示在标题上。 谢谢。如果可能,请发布目标代码,尤其是我想输出像数组一样的数组。 @ios 正如您所提到的,您想连续显示日期,在这种情况下,您需要执行所有代码。如果您只想要部分,那么您可以执行第 3 点。如果您不想排序,请在第 3 点执行 let arrDateKey = Array(dictGroupDate.keys) 恐怕,数组的数组不会改变索引,但你可以在第 4 步尝试。做 var newArray = [[String]]() 和里面 for 循环而不是设置 dict,做 newArray.append(sortedTime)【参考方案3】:

一些注意事项: 1)不要将日期保存为字符串,原因有很多: a) 日期使用更少的内存 b) 您可以使用但在考虑时区和跳跃的函数中进行比较和排序。

2) 不要在每个地方都创建格式化程序(即把它们放在外面) 根据苹果:

https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/DataFormatting/Articles/dfDateFormatting10_4.html#//apple_ref/doc/uid/TP40002369-SW10

【讨论】:

以上是关于如何对数组中的日期进行分组?的主要内容,如果未能解决你的问题,请参考以下文章

如何对记录数组的数组中的字段进行分组?

如何根据反应中的状态属性对数组中的元素进行分组?

如何对对象数据的mongodb聚合数组进行分组以对同一日期的数字求和

如何对数组中的连续整数进行分组?

如何对数组中的特定字段进行分组?

如何在js中对数组中的数据进行分组