在 Objective-C 中替代 NSCountedSet 以保持秩序

Alternative to NSCountedSet in Objective-C to keep order

下面的代码满足了我的需要,只是它之后没有被排序。(请不要告诉我它是因为 NSSet 是无序的,我知道。)这不是一个重复的 SO 问题,我也是我花了 40 多分钟阅读所有 "similar" 问题,但它们没有解决问题。

我正在尝试获取 "hourly"、"daily"、"monthly" 视图,了解在给定时间段内发生 "event" 的次数,标记为在图表的 x 轴上标记时间或日期,并在 y 轴上标记它发生的次数。根据我如何设置要显示的字符串的格式,只需按升序对下面的 dictArray 进行排序,它就可以正常工作。那就是问题所在。对于每小时视图,我正在格式化 "datesForEvent" 数组中的字符串,如下所示 [7am, 7am, 7am, 8am, 8am, 11am, 11am, 1pm, 1pm, 3pm, 3pm] 所以当我将其排序回在 NSCountedSet 中,它会像这样在我的图表的 x 轴上显示它:下午 1 点、下午 3 点、早上 7 点、上午 8 点、上午 11 点。显然不好。如果我将我的格式化字符串放入 "datesForEvent" 数组作为这样的日常视图 [sun, sun, sun, mon, mon, tue, wed, wed, wed, wed, thu, thu, fri, fri fri, fri] 它将在 x 轴上像这样排序 fri, mon, sat, sun, thu, tue, wed.同样的事情发生在月视图 "Jul" 将出现在 "Jun" 之前。

这完全有道理,但我不确定如何解决这个问题。问题完全是由我在计算字符串之前格式化字符串的方式引起的。但是,由于所有事件的日期格式长度相同,因此在计数后格式化字符串会抛出给定时间段内某事发生的次数,因此它将所有这些事件视为单次事件而不是一次分组事件,因为它们的时间精确到毫秒。换句话说,任何事件都不会有重复的时间,这也不好。我在 Apple 文档中遇到日期格式、日期组件、日期样式等问题,但无济于事。我目前正在阅读 Predicates 指南,同时希望获得任何类型的帮助。如果能朝着正确的方向推动,我们将不胜感激。

下面是有问题的代码。具有讽刺意味的是,代码没有错误,因为它正在做我要求它做的事情。我需要 NSCountedSet 没有无序部分的功能。

NSCountedSet *countedSet = [[NSCountedSet alloc] initWithArray:self.datesForEvent];

NSMutableArray *groupedArray = [NSMutableArray array];
[countedSet enumerateObjectsUsingBlock:^(id obj, BOOL *stop) {

    [groupedArray addObject:@{@"dates": obj,
                           @"count": @([countedSet countForObject:obj])}];

}];

//This sorting will sort alphabetically so its not good.   
NSArray *orderedArray = [[NSArray alloc]initWithArray:[groupedArray sortedArrayUsingDescriptors:@[[NSSortDescriptor sortDescriptorWithKey:@"dates" ascending:YES]]]];

这里更新了来自@CRD 的评论排序。我从其他工作中真正快速地休息了一下,并想出了这个解决方案来以正确的顺序计算日期,这与不保持顺序的 NSOrderedSet 解决方案不同。但是,由于缺少更好的词,我希望您对它的坚固性或优雅性有意见。我觉得在数组末尾粘贴 [NSNull null] 有点老套?

 #import "ViewController.h"

@interface ViewController ()

@property (nonatomic, strong) NSArray *baseArray;
@property (nonatomic, strong) NSMutableArray *datesArray;
@property (nonatomic, strong) NSMutableArray *countArray;


@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    //Base Array of counts should be - 07/1 (4), 7/2 (3), 7/3 (2), 7/4 (1)
    self.baseArray = @[@"07/01/16",@"07/01/16",@"07/01/16",@"07/01/16",
                       @"07/02/16",@"07/02/16",@"07/02/16",
                       @"07/03/16",@"07/03/16",
                       @"07/04/16"];

    self.datesArray = [[NSMutableArray alloc]init];

    [self.datesArray addObjectsFromArray:self.baseArray];
    [self.datesArray addObject:[NSNull null]];

    self.countArray = [[NSMutableArray alloc]init];

    int marker = 0;
    int counter = 0;

    //For loop for count of elements
for (int i = 0; i < self.datesArray.count; i++) {

    if (self.datesArray[marker] == self.datesArray[i]) {

        counter++;
        NSLog(@"MDate %@ Index %@ Counter: %d Marker: %d", self.datesArray[marker], self.datesArray[i], counter, marker);

    } else if (self.datesArray[marker] != self.datesArray[i]){

        [self.countArray addObject:[NSNumber numberWithInt:counter]];
        NSLog(@"Count is: %d", counter);

        marker = i;
        --i;
        counter = 0;
    } 
}
    NSLog(@"Count Array is: %@", self.countArray);
}

  @end

这就是我最终的结果。

    #import "ViewController.h"

    @interface ViewController ()

@property (nonatomic, strong) NSArray *baseArray;
@property (nonatomic, strong) NSMutableArray *datesArray;
@property (nonatomic, strong) NSMutableArray *countArray;


@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    //Base Array of counts should be - 07/1 (4), 7/2 (3), 7/3 (2), 7/4 (1)
    self.baseArray = @[@"07/01/16",@"07/01/16",@"07/01/16",@"07/01/16",
                       @"07/02/16",@"07/02/16",@"07/02/16",
                       @"07/03/16",@"07/03/16",
                       @"07/04/16"];

    self.datesArray = [[NSMutableArray alloc]init];

    [self.datesArray addObjectsFromArray:self.baseArray];
    [self.datesArray addObject:[NSNull null]];

    self.countArray = [[NSMutableArray alloc]init];

    int marker = 0;
    int counter = 0;

    //For loop for count of elements
for (int i = 0; i < self.datesArray.count; i++) {

    if (self.datesArray[marker] == self.datesArray[i]) {

        counter++;
        NSLog(@"MDate %@ Index %@ Counter: %d Marker: %d", self.datesArray[marker], self.datesArray[i], counter, marker);

    } else if (self.datesArray[marker] != self.datesArray[i]){

        [self.countArray addObject:[NSNumber numberWithInt:counter]];
        NSLog(@"Count is: %d", counter);

        marker = i;
        --i;
        counter = 0;
    } 
}
    NSLog(@"Count Array is: %@", self.countArray);
}

@end