Objective c 在此算法中填充NSArray的最佳方法

Objective c 在此算法中填充NSArray的最佳方法,objective-c,ios,arrays,nsarray,Objective C,Ios,Arrays,Nsarray,我打算制作一个程序,以实现以下目标: Create an NSArray populated with numbers from 1 to 100,000. Loop over some code that deletes certain elements of the NSArray when certain conditions are met. Store the resultant NSArray. 然而,上面的步骤也将循环多次,因此我需要一种快速的方法来制作这个包含100000个元素

我打算制作一个程序,以实现以下目标:

Create an NSArray populated with numbers from 1 to 100,000.
Loop over some code that deletes certain elements of the NSArray when certain conditions are met.
Store the resultant NSArray.
然而,上面的步骤也将循环多次,因此我需要一种快速的方法来制作这个包含100000个元素的NSArray

那么最快的方法是什么呢

除了使用for循环迭代填充数组外,还有其他方法吗?比如一个NSArray方法可以很快为我做到这一点

或者我可以第一次用10万个数字做一个NSArray。然后使用arraywithArray方法创建每个新的NSArray(步骤1)?(这是更快的方法吗?)

或者你有完全不同的想法,可以实现我想要的


编辑:在上面的帖子中将NSArray替换为NSMutableArray

您可以使用快速枚举在数组中搜索

for(NSNumber item in myArrayOfNumbers)
{
   If(some condition)
   {
        NSLog(@"Found an Item: %@",item);
    }
}

我很确定使用c数组创建数组最快,然后从中创建
NSArray
(基准测试即将到来)。根据您想要删除数字的方式,在初始循环中删除数字的速度可能最快:

const int max_num = 100000;
...
id *nums = malloc(max_num * sizeof(*nums));
int c = 0;
for(int i = 1; i <= max_num; i++) {
    if(!should_skip(i)) nums[c++] = @(i);
}
NSArray *nsa = [NSArray arrayWithObjects:nums count:c];

因此,阵列速度更快,但不如我预期的快。

很难提前判断哪种方法最快。我喜欢基于块的函数,例如

NSMutableArray *array = ...; // your mutable array

NSIndexSet *toBeRemoved = [array indexesOfObjectsPassingTest:^BOOL(NSNumber *num, NSUInteger idx, BOOL *stop) {
    // Block is called for each number "num" in the array.
    // return YES if the element should be removed and NO otherwise;
}];
[array removeObjectsAtIndexes:toBeRemoved];

您可能应该从一个正确工作的算法开始,然后使用工具进行分析。

您可能需要重新考虑您在这里所做的工作。问问自己为什么需要这样一个数组。如果您的目标是操作任意大的整数集合,那么您可能更喜欢使用
NSIndexSet
(及其可变的对应项)


如果您真的想以最有效的方式操作
NSArray
,那么您将需要实现一个专门的子类,该子类专门针对此类作业进行了优化

您可能需要查看
NSMutableIndexSet
。它的设计目的是有效地存储数字范围

您可以这样初始化它:

NSMutableIndexSet *set = [[NSMutableIndexSet alloc]
    initWithIndexesInRange:NSMakeRange(1, 100000)];
[set removeIndex:123];
[set removeIndexesInRange:NSMakeRange(400, 10)];
[set enumerateIndexesUsingBlock:^(NSUInteger i, BOOL *stop) {
    NSLog(@"set still includes %lu", (unsigned long)i);
}];
[set enumerateRangesUsingBlock:^(NSRange range, BOOL *stop) {
    NSLog(@"set still includes %lu indexes starting at %lu",
        (unsigned long)range.length, (unsigned long)range.location);
}];
然后您可以从中删除,例如,123,如下所示:

NSMutableIndexSet *set = [[NSMutableIndexSet alloc]
    initWithIndexesInRange:NSMakeRange(1, 100000)];
[set removeIndex:123];
[set removeIndexesInRange:NSMakeRange(400, 10)];
[set enumerateIndexesUsingBlock:^(NSUInteger i, BOOL *stop) {
    NSLog(@"set still includes %lu", (unsigned long)i);
}];
[set enumerateRangesUsingBlock:^(NSRange range, BOOL *stop) {
    NSLog(@"set still includes %lu indexes starting at %lu",
        (unsigned long)range.length, (unsigned long)range.location);
}];
或者,您可以删除400到409,如下所示:

NSMutableIndexSet *set = [[NSMutableIndexSet alloc]
    initWithIndexesInRange:NSMakeRange(1, 100000)];
[set removeIndex:123];
[set removeIndexesInRange:NSMakeRange(400, 10)];
[set enumerateIndexesUsingBlock:^(NSUInteger i, BOOL *stop) {
    NSLog(@"set still includes %lu", (unsigned long)i);
}];
[set enumerateRangesUsingBlock:^(NSRange range, BOOL *stop) {
    NSLog(@"set still includes %lu indexes starting at %lu",
        (unsigned long)range.length, (unsigned long)range.location);
}];
您可以像这样迭代集合中所有剩余的索引:

NSMutableIndexSet *set = [[NSMutableIndexSet alloc]
    initWithIndexesInRange:NSMakeRange(1, 100000)];
[set removeIndex:123];
[set removeIndexesInRange:NSMakeRange(400, 10)];
[set enumerateIndexesUsingBlock:^(NSUInteger i, BOOL *stop) {
    NSLog(@"set still includes %lu", (unsigned long)i);
}];
[set enumerateRangesUsingBlock:^(NSRange range, BOOL *stop) {
    NSLog(@"set still includes %lu indexes starting at %lu",
        (unsigned long)range.length, (unsigned long)range.location);
}];
或者,更有效地,像这样:

NSMutableIndexSet *set = [[NSMutableIndexSet alloc]
    initWithIndexesInRange:NSMakeRange(1, 100000)];
[set removeIndex:123];
[set removeIndexesInRange:NSMakeRange(400, 10)];
[set enumerateIndexesUsingBlock:^(NSUInteger i, BOOL *stop) {
    NSLog(@"set still includes %lu", (unsigned long)i);
}];
[set enumerateRangesUsingBlock:^(NSRange range, BOOL *stop) {
    NSLog(@"set still includes %lu indexes starting at %lu",
        (unsigned long)range.length, (unsigned long)range.location);
}];

为什么需要这个100000个元素的数组?请考虑到我在火车上的手机上,所以布局不好。应该注意的是,使用快速枚举时不能修改数组。+1,不仅更快,而且更轻。NSArray将因将其内容编入索引而受到处罚。