19

In PHP it's one line of code:

$array_without_empty_strs = array_filter($array_with_empty_strs);

What's the objective C equivalent?

UPDATE - Added the following test code to illustrate the use of Nikolai Ruhe's solution:

// SOLUTION Test Code
NSMutableArray *myArray = [[NSMutableArray alloc] init ];
[myArray addObject:[NSNumber numberWithInt:5]];
[myArray addObject:@""];
[myArray addObject:@"test"];
NSLog(@"%@", myArray);
[myArray removeObject:@""];
NSLog(@"%@", myArray);

// SOLUTION Test Code Output
2012-07-12 08:18:16.271 Calculator[1527:f803] (
    5,
    "",
    test
)
2012-07-12 08:18:16.273 Calculator[1527:f803] (
    5,
    test
)
John Erck
  • 9,478
  • 8
  • 61
  • 71

5 Answers5

64

It's even more simple:

[mutableArrayOfStrings removeObject:@""];

If your array is not mutable you have to create a mutableCopy before.

removeObject: removes all objects from an array that return YES from isEqual:.

Nikolai Ruhe
  • 81,520
  • 17
  • 180
  • 200
29
NSArray *noEmptyStrings = [maybeEmptyStrings filteredArrayUsingPredicate:
    [NSPredicate predicateWithFormat:@"length > 0"]];
rob mayoff
  • 375,296
  • 67
  • 796
  • 848
4

we can use NSPredicate here my code

NSPredicate *pred = [NSPredicate predicateWithBlock:^BOOL(id str, NSDictionary *unused) {
            return ![str isEqualToString:@""];
        }];

        NSArray *filtered = [yourArray filteredArrayUsingPredicate:pred];
balkaran singh
  • 2,754
  • 1
  • 17
  • 32
1

Look at this question, which is almost exactly the same as yours.

I use this method for non-string (object) cases that don't work with NSPredicate

Where array is NSMutableArray

- (void) clearArrayOut
{

    for (int j=[array count]-1; j>=0; j--)
        if ([[array objectAtIndex:j] length] == 0)
            [array removeObjectAtIndex:j];
}

And I totally just stole this from rob mayoff's beautiful answer on my question NSPredicate instead of loop to filter an array of objects

Community
  • 1
  • 1
Dustin
  • 6,783
  • 4
  • 36
  • 53
  • This isn't flexible at all! In fact, its a really really bad way to solve this problem, not only performance wise. Look at rob mayoff's answer to see how its done flexible. – JustSid Jul 11 '12 at 18:44
  • @DustinRowland The link you gave shows a completely different answer than yours! Also, you should make yourself familiar with predicates if you use something like this in your own code, predicates CAN invoke methods, custom objects are not an excuse for this kind of code! – JustSid Jul 11 '12 at 18:49
  • @DustinRowland Besides, your code would be much faster if you decremented `j` instead of starting the loop over again. – JustSid Jul 11 '12 at 18:50
  • @JustSid I just adapted this from a Java project, and Java whines if you decrement the loop counter. – Dustin Jul 11 '12 at 18:51
  • @RaymondWang Whoops! You are right... A case of being to fast on the draw. I will remove the comments. – idz Jul 11 '12 at 18:55
  • If anyone wants to tell me how to make this better I have just posted a question about it! Upvotes shall abound! @JustSid http://stackoverflow.com/q/11439492/1487063 – Dustin Jul 11 '12 at 18:56
  • @DustinRowland Apologies, my bad, when you remove at least one item from the array before the recursive call you do avoid it becoming O(n^2) and pointed out by Raymond Wang. – idz Jul 11 '12 at 18:57
  • @idz it's fine, I just wrote this method quickly in order to throw in a new feature requested by a client. For large values that involve many removals you are correct that it is much worse than O(n). – Dustin Jul 11 '12 at 18:59
  • @DustinRowland Thanks, I think what probably prompted a fair amount of the criticism was the use of recursion in something that can be solved simply with iteration. – idz Jul 11 '12 at 19:06
1

Here's an alternate method that is more flexible even than using a predicate.

NSArray* filteredArray = [arrayToFilter objectsWithIndexes: 
                              [arrayToFilter indexesOfObjectsPassingTest: 
                                 ^((id obj, NSUInteger idx, BOOL *stop)
                                 {
                                     return [obj length] > 0;
                                 }]];
JeremyP
  • 84,577
  • 15
  • 123
  • 161