在不使用循环但使用游标的情况下穿越 NSArray?

Posted

技术标签:

【中文标题】在不使用循环但使用游标的情况下穿越 NSArray?【英文标题】:Travel through NSArray without using loop but cursors? 【发布时间】:2014-04-13 20:16:23 【问题描述】:

我有一个 NSArray,里面有对象 (CLLocation)。我可以在里面有 50、100、300 或更多的物体。事实上,这个数组是在用户行走时使用的,并且可以跟随一个方向。但是用户可以从我的NSArray 中间开始,你懂我的意思吗?

好吧,我必须一直循环我的数组才能知道我的用户在哪里与我的数组中的位置进行比较。

我的问题是:是否可以在列表中使用带有“光标”的 Java 之类的东西,然后简单地调用“下一个对象”来在我的数组中移动而不是循环?

因为我需要用户在我的阵列的所有位置上行走。 示例:

    我的数组计数:100 用户从索引 34 处的位置开始(找到的最近位置) 用户必须执行 35、36、37... 100 AND 0,1,2,3 ... 直到 33。

希望很清楚,如果不使用 for 循环,我真的不知道该怎么做......

感谢您的帮助和建议!

问候, 拉皮努。

【问题讨论】:

为什么不直接使用数组索引。 您是否尝试过存储索引并编写方法来管理索引和对象访问? 不是,但我认为我需要的是一个迭代器。 我不确定你的意思。你知道总是知道你想通过的数字吗? 【参考方案1】:

这是一种方法:

NSArray * arr = ... yourArray

int index = [arr indexOfObject:currentLocation];
index ++;
if (index == arr.count) index = 0;
id nextLocation = arr[index];

另一个可能是创建一个全局计数器变量来存储当前位置。如果这些需要在用户关闭应用程序后持续存在,您可以将其写入用户默认值

【讨论】:

如果我使用它,它将无法工作,因为 currentLocation 对象不在我的数组中... 当它是活动对象时,你会从数组中删除它吗?【参考方案2】:

看起来你想使用NSEnumerator

NSEnumerator Class Reference

NSArray *anArray = // ... ;
NSEnumerator *enumerator = [anArray objectEnumerator];
id object;

while ((object = [enumerator nextObject])) 
    // do something with object...

【讨论】:

枚举器的问题在于它从头开始,在结尾结束。 OP 希望从索引 m 开始并在 m-1 结束。 @Caleb 不难用subarrayWithRange: 制作子数组并将枚举器与结果数组一起使用 不,这并不难,而且重新排列数组以使项目0..m-1 移到末尾而m 成为开头也不难。但是您在此答案中没有提到任何一种可能性。如果您必须关心枚举两个子数组,那么枚举器有多大帮助? 没关系;我没有完全理解环绕。然而,这可以很容易地用@caleb 所说的来实现:创建一个包装你想要的方式的新数组(加入两个子数组)。同样,这就是不可变数组的强大之处。【参考方案3】:

试试这个:

@interface ArrayEnumerator : NSEnumerator

    NSArray* array;
    NSInteger index;
    NSInteger startIndex;
    BOOL over;


- (id)initWithArray:(NSArray*)anArray
            atIndex:(NSInteger)anIndex;
@end
@implementation ArrayEnumerator
- (id)initWithArray:(NSArray*)anArray
            atIndex:(NSInteger)anIndex

    if (self=[super init]) 
        array = anArray;
        index = anIndex;
        startIndex = anIndex;
        over = NO;
    

    return self;


- (id)nextObject

    if (index == [array count]) 
        index = 0;
        over = YES;
    

    if (over && index == startIndex)
        return nil;

    return array[index++];


- (NSArray*)allObjects

    return array;

@end

@implementation ViewController

- (void)viewDidLoad


    NSArray* array = @[@0,@1,@2,@3,@4,@5,@6,@7,@8,@9];
    id element;

    ArrayEnumerator* enumerator = [[ArrayEnumerator alloc] initWithArray:array atIndex:4];
    while (element = [enumerator nextObject])
        NSLog(@"%@", element);



@end

【讨论】:

好的,这可行,但很奇怪。 index 的值永远是错误的。即如果数组中当前位置的索引为 5,则索引的值将为 6。等等... 这基本上是NSEnumerator 的重新实现,但速度较慢且灵活性较差。 @RobNapier 你能在数组中的任意点启动 NSEnumerator 吗? 您还可以使用 for (id object in enumerator) 来遍历它——这并不奇怪 @Fogmeister,是的,通过在subarrayWithRange: 上创建枚举器。这就是不可变数组的力量;这些很便宜。【参考方案4】:

for 循环有什么问题? 迭代器通常用于列表,因为您不能通过索引访问列表中的元素。但是,您正在使用数组,因此您不需要迭代器,而是需要一些以所需顺序访问数组的巧妙方法。 也许这段代码可以为您提供一些想法。这将从 34 运行到 100,然后从 0 开始到 33。

for (int i = 34; i < 134; i++)

    int ix = i % 100;
    id whatever = arr[ix];

【讨论】:

太棒了!非常感谢乔乔:)【参考方案5】:

您可以通过索引访问数组元素:

CLLocation * myLocation = myArray[34];

(或)

int i = 34;

CLLocation * myLocation = myArray[i];

【讨论】:

通过索引访问元素的能力不是数组的定义质量吗?我不认为这一点在 OP 上丢失了。或许您还有更多想说的?

以上是关于在不使用循环但使用游标的情况下穿越 NSArray?的主要内容,如果未能解决你的问题,请参考以下文章

在函数中,如何在不使用 ref 游标的情况下返回多个值?

如何在不使用游标的情况下一次将查询结果分配给多个变量?

在不使用 SQL 游标的情况下插入行和更新表

如何在不使用 Sybase/Perl 中的游标的情况下从表/文件中的 2 行中获取结果集中的一行

在不使用自引用的情况下设置 Objective-C 类属性

如何在不使用 for 循环的情况下填充二维数组?