1

有没有办法让下面的活动更有效率。

+ (NSMutableArray *)sortArrayOfOrdersByDate:(NSMutableArray *)array{

    //create an array of the dates from the Order class
    NSMutableArray *dates = [[NSMutableArray alloc] init];
    for (Order *order in array)
        [dates addObject:[Utility parseDateFromString:order.date format:@"MM-dd-yyyy HH:mm"]];

    //algorithm to sort the array of dates
    NSArray *datesSorted = [dates sortedArrayUsingComparator: 
        ^(id obj1, id obj2) {
             return [obj2 compare:obj1];
        }];

    //match and build a complete, sorted array of orders
    NSMutableArray *ordersSorted = [[NSMutableArray alloc] init];
    for (NSDate *theDate in datesSorted)
        for (Order *order in array)
            if ([[Utility parseStringFromDate:theDate format:@"MM-dd-yyyy HH:mm"] isEqualToString:order.date])
                [ordersSorted addObject:order];

    return ordersSorted;
}

我将解释发生了什么,我有一个名为 Order 的类,它是从数据库中提取的。
由于数据库是不支持日期时间字段的 SQLite,因此我无法从查询中按日期排序,这就是我编写此函数的原因。

订单有一个属性“日期”,它只是一个文本字符串。
为此,我正在使用该值的日期解析版本创建一个 NSDates 数组。

我对日期进行排序,然后尝试通过将每个日期的字符串解析版本与存储在 order.date 中的内容进行比较来创建一个新数组

我的测试数据库中有大约 80 个订单,点击打开视图控制器的按钮有明显的延迟。

任何人都可以帮助提高效率吗,我知道目前它很hacky?

结果

在@bbum 的建议下,我将属性解析并存储order.dateNSDate从数据库中出来的属性,然后使用一个简单的sortedArrayUsingComparator:调用来轻松比较order.date属性。

解决方法见下文:

+ (NSArray *)sortArrayOfOrdersByDate:(NSMutableArray *)array{
    return [array sortedArrayUsingComparator:^(id obj1, id obj2) {
        return [((Order *)obj2).date compare:((Order *)obj1).date];
    }];
}

没有解析/解析使这个解决方案更快,而且,我设法剪掉了双循环和它上面的单循环。

4

2 回答 2

2

最好的解决方案是以可排序的格式在 SQLITE 中表示日期;# 自纪元以来的秒数是典型的。然后您可以按照@bengoesboom 的建议使用 ORDER BY。

如果你不能这样做,那么你可以将这两个循环折叠成一个sortedArrayUsingComparator:对比较器进行转换的调用。

当然,这会非常慢,因为您将反复解析日期。您确实需要将对象中的日期表示为NSDates,可能是在从数据库中获取时进行转换。

而且,当然,我希望您至少使用 FMDB 之类的东西,而不是原始的 SQLite API。同样,如果您不需要数据格式可移植性,请考虑使用 Core Data。

于 2013-07-04T17:44:05.717 回答
1

两种选择:

A. 如果您控制数据库中记录的格式并希望将日期存储为字符串(而不是数字),则将它们存储为字符串格式yyyy-MM-dd HH:mm。这样的日期仍然是人类可读的,并且也可以作为字符串正确排序。您现在可以使用 SQL 查询来提取已排序的记录。

B. 如果你不能控制上面的格式,那么你可以改进算法。

您可以考虑直接对订单数组进行排序,但如果这样做,您将多次将字符串转换为日期,并且这样做的成本可能很高。

另一种选择是创建一个 {date, order} 对数组,按日期排序该数组,对的第一个元素,然后你的订单,对的第二个元素的顺序正确。然后,您可以解压缩这些对并制作一个排序订单数组。为此,您需要为对等定义一个类。

第三种选择,也许是加速/简化的最佳组合是用日期数组和日期字典替换上面的对 -> 订单。字典基于散列 - O(1) - 所以很快。这样做的大纲是(即未经测试的代码):

+ (NSMutableArray *)sortArrayOfOrdersByDate:(NSMutableArray *)array
{

    //create an array of the dates from the Order class
    NSMutableArray *dates = [NSMutableArray new];
    NSMutableDictionary *dateToOrder = [NSMutableDictionary new];

    for (Order *order in array)
    {
        NSDate *orderDate = [Utility parseDateFromString:order.date format:@"MM-dd-yyyy HH:mm"];
        [dates addObject:orderdate];
        [dateToOrder addObject:order forKey:orderDate];
    }

    //algorithm to sort the array of dates
    NSArray *datesSorted = [dates sortedArrayUsingComparator: 
        ^(id obj1, id obj2) {
             return [obj2 compare:obj1];
        }];

    // O(n) extraction of sorted orders
    // notFoundMarker unused as dates only contains keys in the dictionary
    NSArray *ordersSorted = [dateToOrder objectsForKeys:dates notFoundMarker:[NSNull null]];

    return ordersSorted;
}
于 2013-07-04T18:44:56.930 回答