 Shai Givati - 3 years ago 167
Objective-C Question

# Reordering NSMutableArray by changing its starting index (Circular buffer)

Is there an efficient way to reorder NSMutableArray by changing its starting index? Example: if my array is [A,B,C,D,E], I would like to set 3rd element as starting element, and thus create the array [C,D,E,A,B].
I am doing it by slicing the array into two separate array, and then concatenating them. Is there a more efficient or clean way to do this?

Edit: the following is my current code

``````NSArray myArray = [self getMyArray]; // [A,B,C,D]
int startingIndex = 2;
NSArray *subArray1 = [myArray subarrayWithRange:NSMakeRange(_startingIndex, [myArray count] - _startingIndex + 1)]; // [C,D]
NSArray *subArray2 = [myArray subarrayWithRange:NSMakeRange(0, _startingIndex - 1)]; //[A,B]
NSMutableArray *reorderedArray = [NSMutableArray arrayWithArray:subArray1];
`````` dasblinkenlight

The most economical way of rotating `NSMutableArray` in terms of additional memory is the double-reversion algorithm described in this Q&A, because it does not require any additional storage. The idea is to reverse the entire array, and then reverse the two ranges separately.

In your example the array would be reversed, like this

``````E D C B A
``````

then the first three elements would be reversed

``````C D E B A
``````

and finally the tail of the array would be reversed:

``````C D E A B
``````

Make a helper function for reversing a range, and call it three times:

``````reverseInPlace(myArray, 0, myArray.count-1);
reverseInPlace(myArray, 0, _startingIndex);
reverseInPlace(myArray, _startingIndex+1, myArray.count-1);
``````

One way to implement `reverseInPlace` is as follows:

``````static void reverseInPlace(NSMutableArray *a, int f, int b) {
while (f < b) {
[a exchangeObjectAtIndex:f++ withObjectAtIndex:b--];
}
}
``````
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download