I have an empty mutable array. Is it possible to insert object at index 2 for example, while there's nothing at index 0 and 1? I mean to increase capacity dynamically or something like that. .Regards.
-
1Hmm why would you wanna do that? :) – Mikael Jun 21 '11 at 18:34
-
2I need it for my mini project in university. :) – GeRyCh Jun 22 '11 at 07:04
3 Answers
NSMutableArray
is not a sparse array; it does not allow empty slots that can be filled in later. initWithCapacity:
just hints to the array that it will be filled to a certain amount; it isn't generally necessary in practice and, unless you know exactly how many items you are going to shove in the array, don't bother calling it (just use init
).
A mutable array will quite efficiently grow in size as objects are added.
If you need a data structure that supports "holes", then either use something else or put a placeholder object in the slots that are supposed to be empty.
I.e. if you wanted an array with 10 slots, you might do:
NSMutableArray *a = [NSMutableArray array];
for(int i = 0; i<10; i++) [a addObject: [NSNull null]];
You can then check if the retrieved object isEqual: [NSNull null]
to know if the slot is empty or not. And you can use replaceObjectAtIndex:withObject:
to stick an object at a specific index.
Or you could use a different data structure; a dictionary with the indices as the keys would work, for example.

- 162,346
- 23
- 271
- 359
-
You can add a couple of category methods to automatically append `NSNull` objects as needed and check whether an element is the null object and return nil instead. This is how I did it: http://cutecoder.org/programming/behold-holy-array/ – adib Oct 03 '12 at 05:45
You can use a NSPointerArray for that.
NSPointerArray is a mutable collection modeled after NSArray but it can also hold NULL values, which can be inserted or extracted (and which contribute to the object’s count). Moreover, unlike traditional arrays, you can set the count of the array directly.
NSPointerArray
is available in OS X v10.5 and later and iOS 6.0 and later. If you target a lower OS version you can, for example:
Use a
NSMutableDictionary
, wrap you indices intoNSNumber
s and use these as keys.Use a
NSMutableArray
and fill the "holes" withNSNull
objects.

- 28,492
- 6
- 64
- 71
-
Yup; I should have mentioned this. NSPointerArray is an awesomely useful class! However, NSPointerArray isn't available on iOS IIRC. – bbum Jun 21 '11 at 18:36
-
1
Write yourself a SparseArray class using an underlying NSMutableDictionary. Something like this (minimal code, barely tested, but it should give you the idea).
@interface SparseArray : NSObject {
@private
NSMutableDictionary* _dict;
int count;
}
-(SparseArray*)initWithCapacity:(NSUInteger)anInt;
-(id)objectAtIndex:(int)anIndex;
-(void)insertObject:(id)anObject atIndex:(int)anIndex;
- (void)removeObjectAtIndex:(int)anIndex;
-(int)count;
@implementation SparseArray
-(SparseArray*)initWithCapacity:(NSUInteger)anInt {
if ((self = [super init])) {
_dict = [[NSMutableDictionary dictionaryWithCapacity:anInt] retain];
count = 0;
}
return self;
}
-(id)objectAtIndex:(int)anIndex {
NSNumber* key = [NSNumber numberWithInt:anIndex];
id object = [_dict objectForKey:key];
return object;
}
-(void)insertObject:(id)anObject atIndex:(int)anIndex {
NSNumber* key = [NSNumber numberWithInt:anIndex];
[_dict setObject:anObject forKey:key];
count++;
}
- (void)removeObjectAtIndex:(int)anIndex {
NSNumber* key = [NSNumber numberWithInt:anIndex];
id object = [_dict objectForKey:key];
if (object) {
[_dict removeObjectForKey:key];
count--;
}
}
-(int)count {
return count;
}
-(void)dealloc {
[_dict release];
[super dealloc];
}
@end

- 13,526
- 3
- 52
- 57
-
2Unfortunately, this object does not support fast enumeration. Even if you did add it by adopting `NSFastEnumeration` the implementation would either be very inefficient or would not guarantee the enumeration would be ordered (as you'd expect from an array object). – jhabbott Nov 26 '11 at 21:55