diff --git a/Source/NSDictionary.m b/Source/NSDictionary.m index 507b71705..9dad8eb7c 100644 --- a/Source/NSDictionary.m +++ b/Source/NSDictionary.m @@ -29,6 +29,7 @@ #import "common.h" #import "Foundation/NSDictionary.h" #import "Foundation/NSArray.h" +#import "Foundation/NSOrderedSet.h" #import "Foundation/NSData.h" #import "Foundation/NSException.h" #import "Foundation/NSAutoreleasePool.h" @@ -176,7 +177,8 @@ static SEL appSel; GS_DISPATCH_CREATE_QUEUE_AND_GROUP_FOR_ENUMERATION(enumQueue, opts) FOR_IN(id, key, enumerator) obj = (*objectForKey)(self, objectForKeySelector, key); - GS_DISPATCH_SUBMIT_BLOCK(enumQueueGroup, enumQueue, if (shouldStop){return;};, return;, aBlock, key, obj, &shouldStop); + GS_DISPATCH_SUBMIT_BLOCK(enumQueueGroup, enumQueue, + if (shouldStop){return;};, return;, aBlock, key, obj, &shouldStop); if (YES == shouldStop) { break; @@ -860,10 +862,10 @@ static SEL appSel; } } -- (void)getObjects: (__unsafe_unretained id[])objects - andKeys: (__unsafe_unretained id[])keys +- (void) getObjects: (__unsafe_unretained id[])objects + andKeys: (__unsafe_unretained id[])keys { - NSUInteger i=0; + NSUInteger i = 0; FOR_IN(id, key, self) if (keys != NULL) keys[i] = key; if (objects != NULL) objects[i] = [self objectForKey: key]; @@ -949,17 +951,29 @@ compareIt(id o1, id o2, void* context) return k; } -- (NSArray *)keysSortedByValueUsingComparator: (NSComparator)cmptr +- (NSArray *) keysSortedByValueUsingComparator: (NSComparator)cmptr { - return [self keysSortedByValueWithOptions:0 - usingComparator:cmptr]; + return [self keysSortedByValueWithOptions: 0 + usingComparator: cmptr]; } -- (NSArray *)keysSortedByValueWithOptions: (NSSortOptions)opts - usingComparator: (NSComparator)cmptr +- (NSArray *) keysSortedByValueWithOptions: (NSSortOptions)opts + usingComparator: (NSComparator)cmptr { - return [[self allKeys] sortedArrayWithOptions: opts - usingComparator: cmptr]; + CREATE_AUTORELEASE_POOL(arp); + NSArray *sortedValues; + NSArray *noDuplicates; + NSMutableArray *result; + + sortedValues = [[self allValues] sortedArrayWithOptions: opts + usingComparator: cmptr]; + noDuplicates = [[NSOrderedSet orderedSetWithArray: sortedValues] array]; + result = [[NSMutableArray alloc] initWithCapacity: [sortedValues count]]; + FOR_IN(NSObject*, value, noDuplicates) + [result addObjectsFromArray: [self allKeysForObject: value]]; + END_FOR_IN(noDuplicates) + RELEASE(arp); + return AUTORELEASE(result); } /** diff --git a/Tests/base/NSDictionary/sort.m b/Tests/base/NSDictionary/sort.m new file mode 100644 index 000000000..a549b5ba7 --- /dev/null +++ b/Tests/base/NSDictionary/sort.m @@ -0,0 +1,60 @@ +#import "Testing.h" +#import "ObjectTesting.h" +#import +#import +#import +#import + +int main() +{ + START_SET("NSDictionary Sorting") + NSDictionary *d; + NSArray *keysOrderedByKeyedValue; + + NSArray *values = [NSArray arrayWithObjects: + [NSNumber numberWithFloat: 2.0], + [NSNumber numberWithFloat: 1.0], + [NSNumber numberWithFloat: 3.0], + [NSNumber numberWithFloat: 4.0], + nil]; + + NSArray *keys = [NSArray arrayWithObjects: + @"shouldSortToSecond", + @"shouldSortToFirst", + @"shouldSortToThird", + @"shouldSortToFourth", + nil]; + + NSArray *expected = [NSArray arrayWithObjects: + @"shouldSortToFirst", + @"shouldSortToSecond", + @"shouldSortToThird", + @"shouldSortToFourth", + nil]; + + d = [NSDictionary dictionaryWithObjects: values forKeys: keys]; + keysOrderedByKeyedValue = [d keysSortedByValueUsingSelector: + @selector(compare:)]; + + PASS([keysOrderedByKeyedValue isEqual: expected], + "Can sort a dictionary's keys by its values using a selector"); +# ifndef __has_feature +# define __has_feature(x) 0 +# endif +# if __has_feature(blocks) + d = [NSDictionary dictionaryWithObjects: values forKeys: keys]; + keysOrderedByKeyedValue = [d keysSortedByValueUsingComparator: + ^NSComparisonResult(id obj1, id obj2) { + return [(NSNumber*)obj1 compare: (NSNumber*)obj2]; + }]; + + PASS([keysOrderedByKeyedValue isEqual: expected], + "Can sort a dictionary's keys by its values using a comparator"); +# else + SKIP("No Blocks support in the compiler.") +# endif + + END_SET("NSDictionary Sorting") + + return 0; +}