Skip to content

Instantly share code, notes, and snippets.

@grgcombs
Last active May 18, 2017 17:54
Show Gist options
  • Save grgcombs/6a9a6972b05b1707482d3b661ccf0c28 to your computer and use it in GitHub Desktop.
Save grgcombs/6a9a6972b05b1707482d3b661ccf0c28 to your computer and use it in GitHub Desktop.
Sorting a collection of people by NSPersonNameComponents
```obj-c
/**
* Sorting by NSPersonNameComponents
* Assuming you have a collection of people objects, each with a property pointing to a
* (populated) NSPersonNameComponents object...
**/
@interface MyPeepsClass : HashableCodeableArchivableSuperClass
@property (nonatomic,strong) NSPersonNameComponents *nameComponents;
@end
NSArray<MyPeepsClass *>*people = @[person1,
person2,
person3,
....
personN
];
/**
This is how you can sort them (the people).
Create a catagory on NSPersonNameComponents that implements compare: ...
Then .... sort!
**/
NSString *componentsKey = NSStringFromSelector(nameComponents);
NSSortDescriptor *sortByComponents = [NSSortDescriptor sortDescriptorWithKey:componentsKey ascending:YES]
NSArray *sorted = [people sortedArrayUsingDescriptors:@[sortByComponents]];
#import <Foundation/Foundation.h>
@interface NSPersonNameComponents(Sort)
- (NSComparisonResult)compare:(NSPersonNameComponents *)other;
- (NSComparisonResult)compare:(NSPersonNameComponents *)other options:(NSStringCompareOptions)mask;
@end
#import "NSPersonNameComponents+Sort.h"
#import "TXLTypeCheck.h"
@implementation NSPersonNameComponents(Sort)
- (NSComparisonResult)compare:(NSPersonNameComponents *)other
{
other = TXLValueIfClass(NSPersonNameComponents, other);
if (!other)
return NSOrderedDescending;
NSArray *keys = @[NSStringFromSelector(@selector(familyName)),
NSStringFromSelector(@selector(givenName)),
NSStringFromSelector(@selector(nameSuffix)),
NSStringFromSelector(@selector(namePrefix)),
];
NSComparisonResult result = NSOrderedSame;
for (NSString *key in keys)
{
NSString *mine = (NSString *)([[self valueForKey:key] isKindOfClass:NSString.class]) ? [self valueForKey:key] : nil;
NSString *theirs = (NSString *)([[other valueForKey:key] isKindOfClass:NSString.class]) ? [other valueForKey:key] : nil;
if (mine && !theirs)
return NSOrderedDescending;
if (!mine && theirs)
return NSOrderedAscending;
if (mine)
result = [mine compare:theirs];
else if (theirs)
result = NSOrderedAscending;
if (result != NSOrderedSame)
return result;
}
return result;
}
- (NSComparisonResult)compare:(NSPersonNameComponents *)other options:(NSStringCompareOptions)mask
{
other = (NSPersonNameComponents *)([other isKindOfClass:NSPersonNameComponents.class]) ? other : nil;
if (!other)
return NSOrderedDescending;
NSArray *keys = @[NSStringFromSelector(@selector(familyName)),
NSStringFromSelector(@selector(givenName)),
NSStringFromSelector(@selector(nameSuffix)),
NSStringFromSelector(@selector(namePrefix)),
];
NSComparisonResult result = NSOrderedSame;
for (NSString *key in keys)
{
NSString *mine = (NSString *)([[self valueForKey:key] isKindOfClass:NSString.class]) ? [self valueForKey:key] : nil;
if (!mine.length)
mine = nil;
NSString *theirs = (NSString *)([[other valueForKey:key] isKindOfClass:NSString.class]) ? [other valueForKey:key] : nil;
if (!theirs.length)
theirs = nil;
if (mine && !theirs)
return NSOrderedDescending;
if (!mine && theirs)
return NSOrderedAscending;
if (mine)
result = [mine compare:theirs options:mask];
else if (theirs)
result = NSOrderedAscending;
if (result != NSOrderedSame)
return result;
}
return result;
}
@end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment