【问题标题】:Sort NSDictionaries in NSMutableArray by NSDate按 NSDate 对 NSMutableArray 中的 NSDictionaries 进行排序
【发布时间】:2011-10-02 19:37:30
【问题描述】:

我有一个带有字典的 NSMutableArray,所有的字典都包含一个 NSDate,它是 NSString 的形式,键为“日期”。我想按日期对 NSDictionaries 进行排序。因此,例如我有以下数组状态:

Dict
   Date
      20.06.1996 23:30
Dict
   Date
      04.10.2011 19:00
Dict
   Date
      20.06.1956 23:39

我想对其进行排序,使其看起来像这样:

Dict
   Date
      20.06.1956 23:39
Dict
   Date
      20.06.1996 23:30
Dict
   Date
      04.10.2011 19:00

我已经尝试过 NSSortDescriptor,但没有成功...

更新:

我已经设法对日期进行排序,但我遇到了这个问题:在字典中不仅有日期,还有其他对象,我的代码所做的是它只在字典之间切换日期值,而不是切换周围的完整听写。这样一来,字典中的其他值被分配了错误的日期,这非常糟糕。有谁能够帮助我?这是我的代码:

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *path = [documentsDirectory stringByAppendingPathComponent:@"savedData.daf"];
NSMutableArray *d = [NSMutableArray arrayWithContentsOfFile:path];



for (int ii = 0; ii < [d count]; ii++) {
    NSDateFormatter* dateFormatter = [[NSDateFormatter alloc] init];
    if (is24h) {
        [dateFormatter setDateFormat:@"dd.MM.yyyy HH:mm"];
    }
    else {
        [dateFormatter setDateFormat:@"dd.MM.yyyy hh:mm a"];
    }
    [dateFormatter setLocale:[NSLocale currentLocale]];
    NSDate *dat = [dateFormatter dateFromString:[[d valueForKey:@"Date"] objectAtIndex:ii]];
    NSMutableDictionary *newDict = [[NSMutableDictionary alloc] init];
    NSDictionary *oldDict = (NSDictionary *)[d objectAtIndex:ii];
    [newDict addEntriesFromDictionary:oldDict];
    [newDict setObject:dat forKey:@"Date"];
    [d replaceObjectAtIndex:ii withObject:newDict];
    [newDict release];
}


NSSortDescriptor *sorter = [[NSSortDescriptor alloc] initWithKey:@"Date" ascending:YES];
NSArray *sorters = [[NSArray alloc] initWithObjects:sorter, nil];
[sorter release];
NSMutableArray *sorted = [NSMutableArray arrayWithArray:[d sortedArrayUsingDescriptors:sorters]];
[sorters release];
NSLog(@"%@",sorted);
for (int ii = 0; ii < [sorted count]; ii++) {
    NSDateFormatter* dateFormatter = [[NSDateFormatter alloc] init];
    if (is24h) {
        [dateFormatter setDateFormat:@"dd.MM.yyyy HH:mm"];
    }
    else {
        [dateFormatter setDateFormat:@"dd.MM.yyyy hh:mm a"];
    }
    [dateFormatter setLocale:[NSLocale currentLocale]];
    NSString *sr = [dateFormatter stringFromDate:[[sorted valueForKey:@"Date"] objectAtIndex:ii]];
    NSMutableDictionary *newDict = [[NSMutableDictionary alloc] init];
    NSDictionary *oldDict = (NSDictionary *)[d objectAtIndex:ii];
    [newDict addEntriesFromDictionary:oldDict];
    [newDict setObject:sr forKey:@"Date"];
    [sorted replaceObjectAtIndex:ii withObject:newDict];
    [newDict release];
}
NSLog(@"before: %@"
      ""
      "after: %@",d,sorted);
[sorted writeToFile:path atomically:YES];

【问题讨论】:

  • 你应该发布你无法使用的代码。
  • 我很困惑。它们是否包含 NSDates 或 NSStrings?你说两个,但是一个对象不能同时是 NSDate 和 NSString。
  • 这是 NSStrings,对不起!

标签: objective-c ios cocoa-touch nsdate


【解决方案1】:

有很多方法可以做到这一点,一种是使用 NSDate 对象而不是 NSStrings(或根据 ISO 8601 格式化的 NSStrings,以便字典排序匹配所需的排序)。然后你可以这样做:

NSSortDescriptor *descriptor = [NSSortDescriptor sortDescriptorWithKey:@"Date" 
                                                             ascending:YES];
[array sortUsingDescriptors:[NSArray arrayWithObject:descriptor]];

或者,如果您不能(或不想)更改数据,您可以随时使用块进行排序:

[array sortUsingComparator:^(id dict1, id dict2) {
    NSDate *date1 = // create NSDate from dict1's Date;
    NSDate *date2 = // create NSDate from dict2's Date;
    return [date1 compare:date2];
}];

当然,这可能会比第一种方法慢,因为您通常最终会创建超过 n 个 NSDate 对象。

【讨论】:

  • 非常感谢,它真的帮助了我,我遇到了另一个问题,在更新的问题中有解释,请检查一下,并尝试帮助我:)
  • 抛开很多不必要的代码,将[d objectAtIndex:ii] 替换为[sorted objectAtIndex:ii] 应该可以解决您的问题。
  • 干杯!就是这样!那不必要的代码呢? :)
  • 您的代码过于复杂。你不需要复制 NSMutableDictionaries(它们是可变的),你不需要来回转换日期等等。
  • 但是我需要将字符串转换为日期来对它们进行排序,然后我需要将它们转换回字符串,因为我的整个应用程序只使用字符串!
【解决方案2】:

有两种选择,一种是将 NSDate 对象放入字典中。

比较字符串的一个问题是您不能只进行字符串比较,因为年份不在字符串的最重要部分。

因此,您需要编写一个比较方法来使用:

- (NSArray *)sortedArrayUsingComparator:(NSComparator)cmptr

或许:

- (NSArray *)sortedArrayUsingFunction:(NSInteger (*)(id, id, void *))comparator context:(void *)context

比较器需要处理dd.mm.yyyy hh:mm 字符串格式。

其他选项包括添加另一个具有 NSDate 表示的字典键并对其进行排序。

【讨论】:

  • 能否再给我一些代码,我想不通!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多