From 155bec0aca85446958c9372b989fd78e1489ee91 Mon Sep 17 00:00:00 2001 From: Patryk Laurent Date: Mon, 2 Sep 2019 15:38:35 -0700 Subject: [PATCH 1/7] Add (failing) test for keysSortedByValueUsingComparator: --- Tests/base/NSDictionary/sort.m | 41 ++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 Tests/base/NSDictionary/sort.m diff --git a/Tests/base/NSDictionary/sort.m b/Tests/base/NSDictionary/sort.m new file mode 100644 index 000000000..d753f7be4 --- /dev/null +++ b/Tests/base/NSDictionary/sort.m @@ -0,0 +1,41 @@ +#import "Testing.h" +#import "ObjectTesting.h" +#import +#import + +int main() +{ + NSAutoreleasePool *arp = [NSAutoreleasePool new]; + + 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]; + + NSDictionary *d = [NSDictionary dictionaryWithObjects:values forKeys:keys]; + NSArray* keysOrderedByKeyedValue = [d keysSortedByValueUsingComparator: + ^NSComparisonResult(id obj1, id obj2) { + return [(NSNumber*)obj1 compare:(NSNumber*)obj2]; + }]; + + NSArray* expected = [NSArray arrayWithObjects: + @"shouldSortToFirst", + @"shouldSortToSecond", + @"shouldSortToThird", + @"shouldSortToFourth", + nil]; + + PASS([keysOrderedByKeyedValue isEqual:expected], "Can sort a dictionary's keys by its values"); + + [arp release]; arp = nil; + return 0; +} From a4ec3d9d6f41a3c3eb314dcced5e2844d9870107 Mon Sep 17 00:00:00 2001 From: Patryk Laurent Date: Mon, 2 Sep 2019 16:00:17 -0700 Subject: [PATCH 2/7] add missing imports --- Tests/base/NSDictionary/sort.m | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Tests/base/NSDictionary/sort.m b/Tests/base/NSDictionary/sort.m index d753f7be4..81ccb71e3 100644 --- a/Tests/base/NSDictionary/sort.m +++ b/Tests/base/NSDictionary/sort.m @@ -2,6 +2,8 @@ #import "ObjectTesting.h" #import #import +#import +#import int main() { From c692d5e5ca7d20e2036a94ca411c29d0d16b2bdd Mon Sep 17 00:00:00 2001 From: Patryk Laurent Date: Tue, 3 Sep 2019 22:31:13 -0700 Subject: [PATCH 3/7] Solution for keysSortedByValueUsingComparator: incl multiple keys with same value --- Source/NSDictionary.m | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/Source/NSDictionary.m b/Source/NSDictionary.m index 507b71705..13304c658 100644 --- a/Source/NSDictionary.m +++ b/Source/NSDictionary.m @@ -29,6 +29,8 @@ #import "common.h" #import "Foundation/NSDictionary.h" #import "Foundation/NSArray.h" +#import "Foundation/NSMutableArray.h" +#import "Foundation/NSOrderedSet.h" #import "Foundation/NSData.h" #import "Foundation/NSException.h" #import "Foundation/NSAutoreleasePool.h" @@ -958,8 +960,13 @@ compareIt(id o1, id o2, void* context) - (NSArray *)keysSortedByValueWithOptions: (NSSortOptions)opts usingComparator: (NSComparator)cmptr { - return [[self allKeys] sortedArrayWithOptions: opts - usingComparator: cmptr]; + NSArray* sortedValues = [[self allValues] sortedArrayWithOptions: opts usingComparator: cmptr]; + NSArray* noDuplicates = [[NSOrderedSet orderedSetWithArray:sortedValues] array]; + NSMutableArray* result = [[NSMutableArray alloc] initWithCapacity:[sortedValues length]]; + for (NSObject* value in noDuplicates) { + [result addObjectsFromArray:[self allKeysForObject:value]]; + } + return result; } /** From 425ffdb02c941ab225a1b997d428b0f792a8bb96 Mon Sep 17 00:00:00 2001 From: Patryk Laurent Date: Tue, 3 Sep 2019 22:33:38 -0700 Subject: [PATCH 4/7] remove nonsensical import --- Source/NSDictionary.m | 1 - 1 file changed, 1 deletion(-) diff --git a/Source/NSDictionary.m b/Source/NSDictionary.m index 13304c658..06fb9aaf8 100644 --- a/Source/NSDictionary.m +++ b/Source/NSDictionary.m @@ -29,7 +29,6 @@ #import "common.h" #import "Foundation/NSDictionary.h" #import "Foundation/NSArray.h" -#import "Foundation/NSMutableArray.h" #import "Foundation/NSOrderedSet.h" #import "Foundation/NSData.h" #import "Foundation/NSException.h" From c8030ce0cb6283e907b3b695e430c2e0b7c7edba Mon Sep 17 00:00:00 2001 From: Patryk Laurent Date: Tue, 3 Sep 2019 23:19:27 -0700 Subject: [PATCH 5/7] call count instead of length --- Source/NSDictionary.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/NSDictionary.m b/Source/NSDictionary.m index 06fb9aaf8..99d2de682 100644 --- a/Source/NSDictionary.m +++ b/Source/NSDictionary.m @@ -961,7 +961,7 @@ compareIt(id o1, id o2, void* context) { NSArray* sortedValues = [[self allValues] sortedArrayWithOptions: opts usingComparator: cmptr]; NSArray* noDuplicates = [[NSOrderedSet orderedSetWithArray:sortedValues] array]; - NSMutableArray* result = [[NSMutableArray alloc] initWithCapacity:[sortedValues length]]; + NSMutableArray* result = [[NSMutableArray alloc] initWithCapacity:[sortedValues count]]; for (NSObject* value in noDuplicates) { [result addObjectsFromArray:[self allKeysForObject:value]]; } From 8363a7f3a1b69056f92261693f0e4c90f65e511d Mon Sep 17 00:00:00 2001 From: Richard Frith-Macdonald Date: Thu, 26 Sep 2019 12:44:25 +0100 Subject: [PATCH 6/7] Added check for blocks availability. Added testcase for sort by selector. Tidied to match coding style --- Tests/base/NSDictionary/sort.m | 69 +++++++++++++++++++++------------- 1 file changed, 43 insertions(+), 26 deletions(-) diff --git a/Tests/base/NSDictionary/sort.m b/Tests/base/NSDictionary/sort.m index 81ccb71e3..a549b5ba7 100644 --- a/Tests/base/NSDictionary/sort.m +++ b/Tests/base/NSDictionary/sort.m @@ -7,37 +7,54 @@ int main() { - NSAutoreleasePool *arp = [NSAutoreleasePool new]; + 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 *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 *keys = [NSArray arrayWithObjects: + @"shouldSortToSecond", + @"shouldSortToFirst", + @"shouldSortToThird", + @"shouldSortToFourth", + nil]; - NSDictionary *d = [NSDictionary dictionaryWithObjects:values forKeys:keys]; - NSArray* keysOrderedByKeyedValue = [d keysSortedByValueUsingComparator: - ^NSComparisonResult(id obj1, id obj2) { - return [(NSNumber*)obj1 compare:(NSNumber*)obj2]; - }]; + NSArray *expected = [NSArray arrayWithObjects: + @"shouldSortToFirst", + @"shouldSortToSecond", + @"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"); + 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") - [arp release]; arp = nil; return 0; } From e8354c57f0a524befd2514bc7610d698f35204da Mon Sep 17 00:00:00 2001 From: Richard Frith-Macdonald Date: Thu, 26 Sep 2019 12:45:25 +0100 Subject: [PATCH 7/7] Fixed memory leak. Tidied up to match coding style. --- Source/NSDictionary.m | 40 ++++++++++++++++++++++++---------------- 1 file changed, 24 insertions(+), 16 deletions(-) diff --git a/Source/NSDictionary.m b/Source/NSDictionary.m index 99d2de682..9dad8eb7c 100644 --- a/Source/NSDictionary.m +++ b/Source/NSDictionary.m @@ -177,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; @@ -861,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]; @@ -950,22 +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 { - NSArray* sortedValues = [[self allValues] sortedArrayWithOptions: opts usingComparator: cmptr]; - NSArray* noDuplicates = [[NSOrderedSet orderedSetWithArray:sortedValues] array]; - NSMutableArray* result = [[NSMutableArray alloc] initWithCapacity:[sortedValues count]]; - for (NSObject* value in noDuplicates) { - [result addObjectsFromArray:[self allKeysForObject:value]]; - } - return result; + 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); } /**