Chromium Dioxide Chromium Dioxide - 3 months ago 15
iOS Question

Can an NSMutableOrderedSet<NSString*> be sorted using an NSSortComparator?

Before instantly assuming this is a duplicate, read on.

I want to sort a large

NSMutableOrderedSet<NSString*>
in an efficient manner.

I know how to sort an
NSMutableOrderedSet<SomeObject*>
using
NSSortComparator
and setting the key to the relevant member of
SomeObject
.

I also know how to sort an array of
SomeObject
using
sortUsingComparator:^(id firstObject, id secondObject).


I also know how to sort an array of, for example,
NSNumber
using
sortedArrayUsingSelector:@selector(compare:)


But what I can't figure out is how to sort an
NSMutableOrderedSet
when the items are native Obj-C objects such as NSString as opposed to user defined objects:


  • NSortComparator
    uses a key, however there is no key if the set contents is an
    NSString
    as opposed to a custom object? So this can't be used? (I notice
    NSSortComparator
    has a
    SEL
    property and I therefore thought it might be possible to set it to
    NSString:compare
    , but its read only).

  • I have found sorting a large array (say about 50,000 items) using
    sortUsingComparator
    is slow (a few seconds) but sorting an
    NSMutableOrderedSet
    containing the same type of elements is virtually instantaneous using
    NSSortComparator
    . Therefore I do not want to sort using sortUsingComparator if slow.

  • I can't see a method of
    NSMutableOrderedSet
    such as
    sortedArrayUsingSelector
    .



So my question is how can I sort the set in an efficient way if I can't use a
sortDescriptor
and if
sortUsingComparitor
is slow?

I could create a
DummyObject
containing nothing but an
NSString
and have
NSMutableOrderedSet<DummyObject*>
and then sort using
NSSortComparator
, but that seems crazy, so there must be a simpler way, but I can't see what that is from the API nor documentation nor past questions.

Answer
NSMutableOrderedSet<NSString*> *set =  [[NSMutableOrderedSet<NSString*> alloc] init];
[set addObject:@"c"];
[set addObject:@"b"];
[set addObject:@"a"];

NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"self" ascending:YES];
[set sortUsingDescriptors:@[sortDescriptor]