In Objective C, is there a one-liner or something small to remove (shorten by one) and return the first element of an array, regardless of its index?
I don't know of a method that returns the item removed, but you can do this using a combination of NSArray#objectAtIndex:0
and NSMutableArray#removeObjectAtIndex:0
. I suppose you could introduce a new method category on NSMutableArray
that implements a shift
method.
Cocoa array objects (NSArray/NSMutableArray) do not provide a one-line equivalent — you would have to read the object first, then remove it. The fact that these classes provide the methods -lastObject
and -removeLastObject
but not -firstObject
and -removeFirstObject
should be a reminder that removing from the front of an array is usually an inefficient operation, since the contents must be shifted (copied) one position forward. This is particular true for arrays in C, which are intrinsically tied with pointers.
If you're working with anything but primitive data types and/or very small arrays, you might want to consider that the behavior of "shifting off" the first element is indicative of a queue data structure. For details on how you might create a queue for objects, see this SO question. Personally, my opinion for that question is that a real queue class provides the cleanest programming idiom. You can even define your own method (perhaps as a category on NSMutableArray or another class) that does provide a one-liner to do what you want:
@interface NSMutableArray (QueueOneLiner)
- (id) removeAndReturnFirstObject; // Verbose, but clearer than "shift"
@end
@implementation NSMutableArray (QueueOneLiner)
- (id) removeAndReturnFirstObject {
id object = [[self objectAtIndex:0] retain];
[self removeObjectAtIndex:0];
return [object autorelease];
}
@end
However, by that point the solution will likely cause more overhead than it's worth, depending on the importance you place on simplicity versus performance of the code that uses it.
That would be a poor thing to do.
Objective-C on the iPhone can actually use most of the performance perks of C.
If you look at some of my other posts, you'll see I'm ADAMANTLY against premature optimization, but when you are coding at the C level, there are just some things you don't do unnecessarilly.
- Move memory
- Duplicate structures
- Allocate sparsely populated memory blocks
- Inner loops
- ... (There are lots more, but my C-life is rusty and, as I said, I'm anti-optimization)
What you probably want is a well-implemented queue. Something that pre-allocates a large enough circular memory structure and then has two pointers that track the first and last bytes.
I'd be pretty surprised to hear that Objective-C didn't have a queue data structure.
Also, don't strive for the one-liners. All the stuff about terse code is overrated. If it makes more sense to call a method, so be it.
If you have an array obj *arr
where obj
is a class/typename and arr
is the array, you can just say arr+1
to get the array without the first element.