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?
-
Are you talking about a bare C-style array, or something like an NSArray/NSMutableArray?Quinn Taylor– Quinn Taylor2009-06-17 21:50:46 +00:00Commented Jun 17, 2009 at 21:50
-
1In the case of a bare C-style array you're in trouble before you get out of the gate: C-style arrays don't include their bounds/valid size information. I suppose you could pass a pointer to the valid size, but that gets ugly...Jeffrey Hantin– Jeffrey Hantin2009-06-17 21:56:32 +00:00Commented Jun 17, 2009 at 21:56
-
1Then again, for a C-style array, *p++ accomplishes something very like a shift.Jeffrey Hantin– Jeffrey Hantin2009-06-17 22:01:20 +00:00Commented Jun 17, 2009 at 22:01
-
I should have mentioned this was a mutable array.ojreadmore– ojreadmore2009-06-18 01:37:34 +00:00Commented Jun 18, 2009 at 1:37
6 Answers
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.
3 Comments
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.
2 Comments
It's certainly too late to assist the original poster, but if you have a plain NSArray and not an NSMutableArray, this works well:
id myData = myArray.firstObject;
myArray = [myArray subarrayWithRange:NSMakeRange(1, myArray.count - 1)];
1 Comment
loc value of 1 is outside that of the NSArray and you throw an NSRangeExceptionCocoa 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.
1 Comment
Use this code,
[arrayName removeObjectAtIndex:0];
this may help you
1 Comment
NSMutableArray (not NSArray)