Skip to content

Instantly share code, notes, and snippets.

@pond
Created February 13, 2011 19:42
Show Gist options
  • Save pond/825008 to your computer and use it in GitHub Desktop.
Save pond/825008 to your computer and use it in GitHub Desktop.
Objective C fragment from Add Folder Icons which removes duplicate folders
/******************************************************************************\
* -removeDuplicatesFromIndices:comparedAgainst:
*
* Pass two pointers to NSIndexSet instances. The first describes indices in
* 'tableContents' which are to be searched. The second describes indices in
* 'tableContents' which are to be compared. If any items from the second set
* of indices are found to have a match in the first set of indices, then the
* matching item in the *first set* is deleted.
*
* A 'match' is defined as 'same value for the @"path" key'. Other keys in the
* dictionaries are ignored. The "-compare:" message is used to match the path
* strings.
*
* The returned autoreleased index set may be useful if you were maintaining
* one or more indices which may have been altered by the deletions.
*
* In: ( NSIndexSet * ) sourceBlock
* Indices describing items in 'tableContents' which are to be
* searched through and possibly removed;
*
* ( NSIndexSet * ) matchBlock
* Indices describing items in 'tableContents' which are each
* compared to all the items in the source block (see above) and, if
* any matches are found, the matched item in the *source block* will
* be deleted.
*
* Out: Autoreleased index set describing the indices that were deleted.
*
* See also: -insertFolder:atIndex:
* -insertFolder:atIndex:WithStyle:
* -removeDuplicatesFromIndices:comparedAgainst:
* -addSubfoldersOf:
\******************************************************************************/
- ( NSIndexSet * ) removeDuplicatesFromIndices: ( NSIndexSet * ) sourceBlock
comparedAgainst: ( NSIndexSet * ) matchBlock
{
NSMutableIndexSet * duplicates = [ NSMutableIndexSet indexSet ];
/* Match against the lower and upper blocks concurrently, adding the index
* of any duplicate found into the 'duplicates' set. For each item in the
* match block we have to scan the whole source block.
*/
[
matchBlock enumerateIndexesUsingBlock: ^ ( NSUInteger matchIndex, BOOL * stop )
{
NSDictionary * matchRecord = [ tableContents objectAtIndex: matchIndex ];
NSString * matchPath = [ matchRecord valueForKey: @"path" ];
NSUInteger found =
[
tableContents indexOfObjectWithOptions: NSEnumerationConcurrent
passingTest: ^ ( id obj, NSUInteger index, BOOL * stop )
{
/* Proceed on the basis that checking for an index in a set
* is comparatively fast, while extracting a string from a
* dictionary and comparing it to another string is
* comparatively slow. Only do the comparision if the index
* is within the source block range and has not been marked
* as a duplicate already.
*/
if (
[ sourceBlock containsIndex: index ] == YES &&
[ duplicates containsIndex: index ] == NO
)
{
NSDictionary * sourceRecord = ( NSDictionary * ) obj;
NSString * sourcePath = [ sourceRecord valueForKey: @"path" ];
if ( [ sourcePath compare: matchPath ] == NSOrderedSame )
{
*stop = YES;
return YES;
}
}
return NO;
}
];
if ( found != NSNotFound ) [ duplicates addIndex: found ];
}
];
/* Now remove all found duplicates in one go */
[ tableContents removeObjectsAtIndexes: duplicates ];
return duplicates;
}
@pond
Copy link
Author

pond commented Feb 13, 2011

Available here too, with better and configurable syntax colouring: http://pastie.org/1560400

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment