-5

I have one array. In that array I want check if array is empty then remove it. I am trying to check that array is nil or count 0 but not working.

Here is my array :

data(
(
abc,
xyz
),
(
yui,
hsjd
),
(
),
)

In data array last array is empty and I want to remove from data array. Please suggest me any idea.

rmaddy
  • 314,917
  • 42
  • 532
  • 579
Test stack
  • 23
  • 3

3 Answers3

2

NOTE: Instead of Downvoting because a question has already been downvoted so It's a fair game, try reading the answer first which contains both stable and potentially unstable ways.

Your data array is basically an array of arrays. Make your data array a NSMutableArray like this:

data = [[NSMutableArray alloc] initWithArray: data];

Now remove the empty enclosed arrays like this:

(Stable Way)

NSMutableIndexSet *itemsToDiscard = [NSMutableIndexSet indexSet];
NSArray *item;
NSUInteger index = 0;

for (item in data) {
    if ([item count]<=0)
        [itemsToDiscard addIndex:index];
    index++;
}

[data removeObjectsAtIndexes:discardedItems];

Or by this approach which is not recommended at all but I am just putting it out there because it is working for me. I suggest however you use the first approach.

(Potentially unstable way)

for(id arr in data) {
    if ([arr isKindOfClass:[NSArray class]])
    {
       if(arr.count<=0)
       { 
          [data removeObject:arr];
       }
    }
}

This will remove the empty arrays enclosed in data.

NSNoob
  • 5,548
  • 6
  • 41
  • 54
  • Why create the `arr` array? Plus, this code will fail if there are two empty arrays in a row. You need to iterate in reverse. – rmaddy Nov 02 '15 at 06:10
  • My bad @rmaddy thanks for pointing it out. How about using for each loop? – NSNoob Nov 02 '15 at 06:12
  • Also as much as I'd accept the downvotes, It would be more helpful to leave a comment for your reason to do so so that I might improve the answer. Like rmaddy did and I improved the answer. – NSNoob Nov 02 '15 at 06:18
  • You can't modify an array being iterated with a `for in` loop. – rmaddy Nov 02 '15 at 06:18
  • @rmaddy I just did that. You can modify that. – NSNoob Nov 02 '15 at 06:23
  • 1
    No, calling `removeObject:` on the mutable array while using the `for in` will result in a crash. – rmaddy Nov 02 '15 at 06:25
  • Are you absolutely sure? it is NOT crashing for me and it is removing the undesired objects form the mutableArray. I have just run it. – NSNoob Nov 02 '15 at 06:26
  • Crashes for me. Are you sure that in your test you are actually removing an object from the mutable array during the loop? – rmaddy Nov 02 '15 at 06:32
  • @rmaddy Doesn't crash for me. You can see it here. http://imgur.com/a/lzsvb. Or should I make a video of it? – NSNoob Nov 02 '15 at 06:37
  • That's really strange. That code crashes for me. And this site is full of examples of such code crashing. I don't know why it is working for you. The docs even say it isn't safe to modify a mutable array while iterating this way. – rmaddy Nov 02 '15 at 06:40
  • @rmaddy it might be so. Anyhow I have edited the answer, would you take a look at it now? – NSNoob Nov 02 '15 at 06:55
  • Smh on piggyback downvote. The answer has been edited with a correct and stable solution. Why one earth would you downvote that? @rmaddy's downvotes were absolutely correct for concrete reasons I have no idea why the second bloke downvoted it. – NSNoob Nov 02 '15 at 07:53
1

Since you are iterating through an array that is changing throughout the iteration, you'll have to use a while-loop with the condition as an index being smaller than the size of the array, like so:

NSMutableArray *arrayContents = [NSMutableArray arrayWithObjects: @[@"abc", @"def"],@[@1,@2,@3], @[], nil];
NSLog( @"Pre while-loop: \n%@", arrayContents);
NSUInteger index = 0;
while (index < [arrayContents count]) {
    BOOL didRemove = false;
    if ([[arrayContents objectAtIndex: index] count] == 0) {
        [arrayContents removeObjectAtIndex: index];
        didRemove = true;

    }
    if (didRemove == false)
        index += 1;

}
NSLog( @"Post while-loop: \n%@", arrayContents);

If nothing was removed, you would increment index, but if something was removed, you don't increment the index. Instead you loop again at the same index, because if you increase the index after removing, you'll "skip" an iteration.

Hope this works for your situation :)

ErickES7
  • 558
  • 6
  • 16
-1

The simple way is to just loop through each subarray in the array, and check if it is empty. Since you cannot delete entries while looping, you can just keep a counter and remove them after.

In Swift 2.0

var arrays = [["abc","def"],["ghi","jkl"],[], ["mno"], [], ["pqr"], [], ["stv"]]
var numberToRemove = 0
for idx in 0..<arrays.count {
if arrays[idx].isEmpty {
    numberToRemove++
    arrays.insert(arrays.removeAtIndex(idx), atIndex: 0)
}
}

arrays.removeRange(0..<numberToRemove)
Alexander Li
  • 781
  • 4
  • 12