在 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
下面的代码满足了我的需要,只是它之后没有被排序。(请不要告诉我它是因为 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