47

How to remove an item from NSArray.

skaffman
  • 398,947
  • 96
  • 818
  • 769
pratik
  • 4,419
  • 8
  • 41
  • 65

7 Answers7

127

NSArray is not mutable, that is, you cannot modify it. You should take a look at NSMutableArray. Check out the "Removing Objects" section, you'll find there many functions that allow you to remove items:

[anArray removeObjectAtIndex: index];
[anArray removeObject: item];
[anArray removeLastObject];
Ja͢ck
  • 170,779
  • 38
  • 263
  • 309
luvieere
  • 37,065
  • 18
  • 127
  • 179
  • 3
    Note: [-removeObject:](https://developer.apple.com/library/ios/documentation/cocoa/reference/foundation/classes/NSMutableArray_Class/Reference/Reference.html#//apple_ref/occ/instm/NSMutableArray/removeObject:) removes **all matching occurrences** in the array. – Pang Mar 13 '14 at 09:17
24
NSMutableArray *arrayThatYouCanRemoveObjects = [NSMutableArray arrayWithArray:your_array];

[arrayThatYouCanRemoveObjects removeObjectAtIndex:your_object_index];

[your_array release];

 your_array = [[NSArray arrayWithArray: arrayThatYouCanRemoveObjects] retain];

that's about it

if you dont own your_array(i.e it's autoreleased) remove the release & retain messages

ahmet emrah
  • 1,858
  • 2
  • 15
  • 22
20

This category may be to your taste. But! Be frugal with its usage; since we are converting to a NSMutableArray and back again, it's not at all efficient.

@implementation NSArray (mxcl)

- (NSArray *)arrayByRemovingObject:(id)obj
{
    if (!obj) return [self copy]; // copy because all array* methods return new arrays
    NSMutableArray *mutableArray = [NSMutableArray arrayWithArray:self];
    [mutableArray removeObject:obj];
    return [NSArray arrayWithArray:mutableArray];
}

@end
Adem
  • 9,402
  • 9
  • 43
  • 58
mxcl
  • 26,392
  • 12
  • 99
  • 98
  • 1
    you're a champion! I had to use the above method because I sort an NSMutableArray, which means that the array I use in my table cells is not mutable. Therefore when I go to remove objects from the array I use your method to do so. – gotnull Feb 06 '11 at 10:34
18

Here's a more functional approach using Key-Value Coding:

@implementation NSArray (Additions)

- (instancetype)arrayByRemovingObject:(id)object {
    return [self filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"SELF != %@", object]];
}

@end
Rudolf Adamkovič
  • 31,030
  • 13
  • 103
  • 118
  • Elegant. May not perform as fast as the other solutions, however. Be sure to test this with large datasets if that's what you're dealing with. – Thomas Tempelmann May 05 '19 at 13:54
4

Made a category like mxcl, but this is slightly faster.

My testing shows ~15% improvement (I could be wrong, feel free to compare the two yourself).

Basically I take the portion of the array thats in front of the object and the portion behind and combine them. Thus excluding the element.

- (NSArray *)prefix_arrayByRemovingObject:(id)object 
{
    if (!object) {
        return self;
    }

    NSUInteger indexOfObject = [self indexOfObject:object];
    NSArray *firstSubArray = [self subarrayWithRange:NSMakeRange(0, indexOfObject)];
    NSArray *secondSubArray = [self subarrayWithRange:NSMakeRange(indexOfObject + 1, self.count - indexOfObject - 1)];
    NSArray *newArray = [firstSubArray arrayByAddingObjectsFromArray:secondSubArray];

    return newArray;
}
Ossir
  • 3,109
  • 1
  • 34
  • 52
jmathew
  • 1,522
  • 17
  • 29
  • `NSArray* newArray = [NSArray array];` initialization here is redundant – Ossir Apr 24 '14 at 14:14
  • 1
    @Ossir You're right the declaration is redundant because the `[self subarray...]` part. @Michael Ozeryansky, if the obj is nil `indexOfObject` will return `NSNotFound`. I'm not sure what happens then but its probably not the right thing, thanks! – jmathew Jun 02 '14 at 15:27
4

Remove Object from NSArray with this Method:

-(NSArray *) removeObjectFromArray:(NSArray *) array withIndex:(NSInteger) index {
    NSMutableArray *modifyableArray = [[NSMutableArray alloc] initWithArray:array];
    [modifyableArray removeObjectAtIndex:index];
    return [[NSArray alloc] initWithArray:modifyableArray];
}
Kai Burghardt
  • 1,493
  • 16
  • 16
0

As others suggested, NSMutableArray has methods to do so but sometimes you are forced to use NSArray, I'd use:

NSArray* newArray = [oldArray subarrayWithRange:NSMakeRange(1, [oldArray count] - 1)];

This way, the oldArray stays as it was but a newArray will be created with the first item removed.

Hadi tavakoli
  • 1,267
  • 2
  • 16
  • 30