Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>If you're making a copy of an array with certain items filtered out, then make a new mutable array, iterate over the original and add to the copy on the fly, as others have suggested for this answer. But your question said removing from an existing (presumably mutable) array.</p> <p>While iterating, you could build an array of objects to remove, and then remove them afterwards:</p> <pre><code>NSMutableArray *thePeople = ... NSString *hairColorToMatch = ... NSMutableArray *matchingObjects = [NSMutableArray array]; for (People *person in thePeople) { if (person.hairColor isEqualToString:hairColorToMatch]) [matchingObjects addObject:person]; [thePeople removeObjects:matchingObjects]; </code></pre> <p>But this creates a temporary array that you might think is wasteful and, more importantly, it's hard to see <code>removeObjects:</code> being very efficient. Also, someone mentioned something about arrays with duplicate items, this should work in that case but wouldn't be the best, with each duplicate also in the temporary array and redundant matching within <code>removeObjects:</code>.</p> <p>One can iterate by index instead and remove as you goes, but that makes the loop logic rather awkward. Instead, I would collect the indexes in an index set and again, remove afterwards:</p> <pre><code>NSMutableIndexSet *matchingIndexes = [NSMutableIndexSet indexSet]; for (NSUInteger n = thePeople.count, i = 0; i &lt; n; ++i) { People *person = thePeople[i]; if ([person.hairColor isEqualToString:hairColorToMatch]) [matchingIndexes addIndex:i]; } [thePeople removeObjectsAtIndexes:matchingIndexes]; </code></pre> <p>I believe index sets have really low overhead so this is nearly as efficient as you'll get and hard to screw up. Another thing about removing in a batch at the end like this is that it's possible that Apple has optimized <code>removeObjectsAtIndexes:</code> to be better than a sequence of <code>removeObjectAtIndex:</code>. So even with the overhead of creating the index set data structure, this may beat out removing on the fly while iterating. This one works pretty well too if the array has duplicates.</p> <p>If instead, you really are making a filtered copy, then I thought there was some <code>KVC</code> collection operator you can use (I was reading about those recently, you can do some crazy things with those according <a href="http://nshipster.com/kvc-collection-operators/" rel="nofollow">NSHipster</a> &amp; <a href="http://kickingbear.com/blog/archives/9" rel="nofollow">Guy English</a>). Apparently no, but close, one needs to use KVC <strong>and</strong> NSPredicate in this somewhat wordy line:</p> <pre><code>NSArray *subsetOfPeople = [allPeople filteredArrayUsingPredicate: [NSPredicate predicateWithFormat:@"SELF.hairColor != %@", hairColorToMatch]]; </code></pre> <p>Do go ahead and create a category on <code>NSArray</code> to make things more concise for your code, <code>filterWithFormat:</code> or something.</p> <p>(all untested, typed directly into SO)</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload