Can I shift the objects in a NSMutableArray withou

2019-06-17 15:27发布

问题:

I thought I had it with,

void shiftArray(NSMutableArray *mutableArray, NSUInteger shift)
{
    for (NSUInteger i = 0; i < [mutableArray count]; i++) {
        NSUInteger newIndex = (i + shift) % [mutableArray count];
        [mutableArray exchangeObjectAtIndex:i withObjectAtIndex:newIndex];
    }
}

which turns 0,1,2,3,4 into 0,2,3,4,1 when I shift by one.

The expected result is 4,0,1,2,3

I feel like I'm missing something obvious...

Update: Thanks Matthieu, this is what my function looks like now.

void shiftArrayRight(NSMutableArray *mutableArray, NSUInteger shift) {
    for (NSUInteger i = shift; i > 0; i--) {
        NSObject *obj = [mutableArray lastObject];
        [mutableArray insertObject:obj atIndex:0];
        [mutableArray removeLastObject];
    }
}

I didn't know you could make a generic NSObject and put some subclass in it. It's all just pointers so I guess it's OK, right?

It's hard to break the habit of thinking of these objects as bags of stuff rather than pointers to the bag.

回答1:

Try something like

for (NSUInteger i = shift; i > 0; i--) {
   NSObject* obj = [mutableArray lastObject];
   [mutableArray insertObject:obj atIndex:0];
   [mutableArray removeLastObject];
}

CAVEAT -- I haven't tested that code, but that should help you solve the problem.



回答2:

You need to look again at your algorithm. Each time through the loop, you exchange one item with (in the case of shift=1) the next one.

0,1,2,3,4
1,0,2,3,4
1,2,0,3,4
1,2,3,0,4
1,2,3,4,0
0,2,3,4,1

You can do the operation you want to do, but you need to think about how to order the steps and their dependencies to get the right result. In the trivial case, you can just work backward from the end.

0,1,2,3,4
4,1,2,3,0
4,1,2,0,3
4,1,0,2,3
4,0,1,2,3