meaning-matters
meaning-matters

Reputation: 22946

How to sort NSSet subset in same order as full set NSArray, using NSPredicate?

My self.allArray contains all my objects. Then self.enabledSet contains a subset of these objects.

To create a sortedEnabledArray I currently do this:

NSArray* enabledArray = [self.enabledSet allObjects];
NSArray* sortedEnabledArray;

sortedEnabledArray = [enabledArray sortedArrayUsingComparator:^NSComparisonResult(id a, id b)
{
    int indexA = [self.allArray indexOfObject:a];
    int indexB = [self.allArray indexOfObject:b];

    if (indexA < indexB)
    {
        return NSOrderedAscending;
    }
    else if (indexA > indexB)
    {
        return NSOrderedDescending;
    }
    else
    {
        return NSOrderedSame;
    }
}];

but I am wondering if this can't be done in a smarter/shorter way, using an NSPredicate for example. Any ideas?

EDIT: One idea to shorten is:

    int difference = indexA - indexB;

    // Convert difference to NSOrderedAscending (-1), NSOrderedSame (0), or NSOrderedDescending (1).
    return (difference != 0) ? (difference / abs(difference)) : 0;

Upvotes: 1

Views: 529

Answers (3)

Duncan C
Duncan C

Reputation: 131471

My suggestion is to use a different approach. There is a companion to NSArray called NSIndexSet (and it's mutable counterpart, NSMutableIndexSet). It is an object that is specifically intended to keep track of subsets of an array that meet a given criteria.

NSArray includes methods like indexesOfObjectsPassingTest (and other variants that include additional parameters.) that let you add the indexes of some members of an array to an index set.

Once you have an index set that represents a subset of your allArray, you could use a method like objectsAtIndexes to get an array of just the selected objects.

Upvotes: 3

LorikMalorik
LorikMalorik

Reputation: 2019

It depends on number of items in your set and array, but you can do this way:

NSPredicate* predicate = [NSPredicate predicateWithBlock:^BOOL(id object, NSDictionary* bindings)
{
    return [self.enabledSet containsObject:object];
}];

NSArray* sortedEnabledArray = [self.allArray filteredArrayUsingPredicate:predicate];

Upvotes: 4

Cy-4AH
Cy-4AH

Reputation: 4585

Store in NSSet not objects, but indexes from allArray array.

Upvotes: 2

Related Questions