首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Obj按日期对表视图数据进行字符串排序?

Obj按日期对表视图数据进行字符串排序?
EN

Stack Overflow用户
提问于 2021-04-12 16:22:15
回答 2查看 64关注 0票数 0

我有一个数组(self.filteredArray),它返回字典,其中键scheduleddate包含今天的日期(在本例中是2021年4月12日)。控制台返回以下内容:

代码语言:javascript
复制
2021-04-12 09:14:30.942723-0700 [58012:24654705] The filtered please (
            {
    
            "node_title" = "Elisa Carmichael";
            scheduleddate = "Apr 12 2021 1:00 PM";
        
        },
            {
           
            "node_title" = "Michael Levy";
            scheduleddate = "Apr 10 2021 11:00 AM, Apr 12 2021 5:00 PM";

        },
            {
            
            "node_title" = "Trisha Johnson";
            scheduleddate = "Apr 12 2021 6:00 PM";

        }
    )

我的目标是把这些人安排在一个“今天”的表中,按照他们预定的时间顺序排列。当计划日期只包含一个日期和时间时,下面的代码工作得很好。4月12日下午1:00但是,有些人在同一个scheduleddate字符串中(在上面的Michael中)调度多个日期和时间,这破坏了排序顺序。

是否有一种方法可以让我编写以下代码,以便最终数组(self.sortedByTime)只通过包含今天日期的",“分隔的值来排列返回的个人?

我希望这是合理的。谢谢。

ViewController.m

代码语言:javascript
复制
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    
        if (tableView == self.todaytableView) {
    
    self.sortedByTime = [self.filteredArray sortedArrayUsingComparator:^NSComparisonResult(NSDictionary *obj1, NSDictionary *obj2)


                {
              
                    int i;
                    for (i = 0; i < [self.filteredArray count]; i++) {
    
      }
                  
                    NSDate *date1 = [dateFormatter dateFromString:obj1[@"scheduleddate"]];
                    NSDate *date2 = [dateFormatter dateFromString:obj2[@"scheduleddate"]];
                    return [date1 compare:date2];
                }];
              
    
                 self.finalTimes = [[NSMutableArray alloc]initWithArray:self.sortedByTime];
    
           
                
            return [self.finalTimes count];
                
            }

我的目标输出:

代码语言:javascript
复制
2021-04-12 09:14:30.942723-0700 [58012:24654705] The filtered please (
            {
    
            "node_title" = "Elisa Carmichael";
            scheduleddate = "Apr 12 2021 1:00 PM";
        
        },
            {
           
            "node_title" = "Michael Levy";
            scheduleddate = "Apr 12 2021 5:00 PM";

        },
            {
            
            "node_title" = "Trisha Johnson";
            scheduleddate = "Apr 12 2021 6:00 PM";

        }
    )
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2021-04-12 16:59:26

你的问题不是排序。是关于过滤和映射的。

为什么?您需要筛选,因为您希望拒绝某些值。您需要“映射”,因为您想要更改一些值。

因此,我们进行手动筛选,因为我们希望同时映射,即:一个简单的for循环,对于每个元素,我们检查日期字符串中是否有一个“今天”日期候选,并保留第一个找到的日期。

代码语言:javascript
复制
NSArray *array = @[@{@"node_title": @"Elisa Carmichael",
                      @"scheduleddate": @"Apr 12 2021 1:00 PM"},
                   @{@"node_title": @"Michael Levy",
                      @"scheduleddate": @"Apr 10 2021 11:00 AM, Apr 12 2021 5:00 PM"},
                   @{@"node_title": @"Trisha Johnson",
                     @"scheduleddate":@"Apr 12 2021 6:00 PM"}];

NSMutableArray *mappedAndfiltered = [[NSMutableArray alloc] init];
for (NSDictionary *aDict in array) {
    NSString *scheduledDatesString = aDict[@"scheduleddate"];
    NSArray *dates = [scheduledDatesString componentsSeparatedByString:@","];
    NSUInteger candidateIndex = [dates indexOfObjectPassingTest:^BOOL(NSString * _Nonnull dateStr, NSUInteger idx, BOOL * _Nonnull stop) {
        return [dateStr containsString:@"Apr 12 2021"]; //That's for the tests, but in fact, use your NSDateFormatter and check if the NSDate is today, I was just lazy to redo a formatter for your sample and check if it's within today
    }];
    if (candidateIndex != NSNotFound) {
        [mappedAndfiltered addObject:@{@"node_title": aDict[@"node_title"],
                                       @"scheduleddate": dates[candidateIndex]}];
    }
}

NSLog(@"mappedAndfiltered: %@", mappedAndfiltered);

//现在,使用当前方法重新排序

我强烈建议使用自定义NSObject (一种模型)。因为您一直在操作NSString,它们应该位于NSDate的位置,并且继续在它们之间进行转换,以便对数据进行排序、编辑等等。字符串表示应该只为用户而不是为开发人员保留。否则,很容易出错。

有一个快速的模型:

代码语言:javascript
复制
@interface MyModel: NSObject
@property (nonatomic, copy) NSString *title;
@property (nonatomic, strong) NSArray *dates;
@property (nonatomic, strong) NSDate *dateWithinToday;

-(id)initWithDict:(NSDictionary *)dict;
-(id)initWithTitle:(NSString *)title dateStrings:(NSArray *)commaSeparatedDateStrings;
@end
@implementation MyModel

-(id)initWithDict:(NSDictionary *)dict {

    if (self == [self initWithTitle:dict[@"node_title"] dateStrings:[dict[@"scheduleddate"] componentsSeparatedByString:@","]]) {

    }
    return self;
}

-(id)initWithTitle:(NSString *)title dateStrings:(NSArray *)commaSeparatedDateStrings {
    if (self == [super init]) {
        _title = title;
        NSMutableArray *datesArray = [[NSMutableArray alloc] init];
        for (NSString *aDateStr in commaSeparatedDateStrings) {
            //Use a "single formatter"
            [datesArray addObject:[__dateFormatter dateFromString:aDateStr]];
        }
        _dates = datesArray;
        NSUInteger index = [datesArray indexOfObjectPassingTest:^BOOL(NSDate * _Nonnull date, NSUInteger idx, BOOL * _Nonnull stop) {
            return [[NSCalendar currentCalendar] isDateInToday:date];
        }];
        if (index != NSNotFound) {
            _dateWithinToday = datesArray[index];
        }
    }
    return self;
}

-(NSString *)description {
    return [NSString stringWithFormat: @"%@ - title: %@ - todaydate: %@ - all dates: %@" , [super description], _title, _dateWithinToday, _dates];
}
@end

并在使用中:

代码语言:javascript
复制
NSMutableArray *arrayOfObjects = [[NSMutableArray alloc] init];
for (NSDictionary *aDict in array) {
    [arrayOfObjects addObject:[[MyModel alloc] initWithDict:aDict]];
}

NSPredicate *todayPredicate = [NSPredicate predicateWithBlock:^BOOL(MyModel * _Nullable aModel, NSDictionary<NSString *,id> * _Nullable bindings) {
    return [aModel dateWithinToday] != nil;
}];
NSArray *filtered = [arrayOfObjects filteredArrayUsingPredicate:todayPredicate];
NSArray *sorted = [filtered sortedArrayUsingComparator:^NSComparisonResult(MyModel * _Nonnull obj1, MyModel * _Nonnull obj2) {
    return [[obj1 dateWithinToday] compare:[obj2 dateWithinToday]];
}];

NSLog(@"sorted: %@", sorted);
票数 0
EN

Stack Overflow用户

发布于 2021-04-12 16:50:32

好的,您希望按照scheduleddate键中的日期值对字典数组进行排序。

如果scheduleddate有时包含多个日期,那么如果您可以假设正确的日期是最后一个日期,则会更简单。如果做不到这一点,就这样做:

编写一个函数dateTodayFromString(_:),该函数接受一个字符串并返回日期。

让它使用NSString方法containsString来确定它是否包含逗号。如果没有,只需应用日期格式化程序并返回结果日期。

如果是这样的话,使用componentsSeparatedByString: ", "将多个日期分开。使用Date将每个日期转换为DateFormatter,循环遍历日期数组,并使用Calendar函数isDateInToday查找当前日期。如果它找到了,就把它还回去。

重写排序函数以调用dateTodayFromString(_:)函数,以便从每个数组条目中的字符串中获取日期。

请注意,如果数组包含的条目超过≈100项,则实际上应该将数组转换为一个可变字典数组,并在尝试对其排序之前,先经过一次传递,将所有日期字符串转换为date对象。每次比较将日期字符串转换为日期使得排序过程要慢得多(我似乎还记得,在一个中等大小的数组上测试它时花费了大约12倍的时间,但我必须回去测试它。)

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67062024

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档