0

Say I have two arrays, one representing a desired order for the other. I'd like to be able to apply the order to the array.

My reasoning is this. My app contains a playlist that can be shuffled and I want to be able to store the shuffled indexes in case a user continues a given playlist later. So, the two main requirements are that I need to be able to extract the indexes of the original playlist in the shuffled list, and later to be able to reapply those indexes to the the original playlist to regenerate the exact same shuffled list (my shuffle method is random, it will be different every time).

Here is my naive approach. My main questions are, what is the most efficient way to do this, and what is the best way to store the "order" array - clearly using an array of NSNumbers is not efficient, but I'm still an amateur and don't know how to do it better.

NSMutableArray *anArray = @[@"this",@"is",@"an",@"array"];
NSArray *numberArray = @[@(1),@(0),@(2),@(3)];
anArray = [self applyOrder:numberArray toArray:anArray];
NSLog(@"%@",anArray);

-(NSMutableArray*)applyOrder:(NSArray *)order toArray:(NSArray *)array
{
    NSMutableArray *newArray = [NSMutableArray array];
    for(int i =0;i<order.count;i++)
    {
        [newArray addObject:[array objectAtIndex:[[order objectAtIndex:i]integerValue]]];
    }

    return newArray;
}
1
  • Not an answer to the question but you can write an NSNumber as a literal by writing @(theNumber) and you can write an NSArray as a literal using @[@"this",@"is",@"an",@"array"]; which also removes the need to nil terminate the array. Commented Nov 20, 2013 at 22:30

2 Answers 2

4

To have the total control over the sorting process, I think the best approach is using sortedArrayUsingComparator: method of NSArray class that takes a block for comparison. You might use the following code for sorting:

NSArray* anArray = @[@"this",@"is",@"an",@"array"];
NSArray* numberArray = @[@(1),@(0),@(2),@(3)];
NSArray* sorted = [anArray sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) {
    NSNumber* i = numberArray[[anArray indexOfObject:obj1]];
    NSNumber* j = numberArray[[anArray indexOfObject:obj2]];
    return [i compare:j];
}];
NSLog(@"%@",sorted);

And by the way, storing the indices in a different array is not at all an inefficient approach (think of the database). :)

Hope you would find it helpful.

Sign up to request clarification or add additional context in comments.

1 Comment

Seems simple enough to me!
1

There is a class designed specifically for this -- NSIndexSet : https://developer.apple.com/library/mac/documentation/cocoa/reference/foundation/classes/NSIndexSet_Class/Reference/Reference.html

And here, at everyone's favorite blog: http://nshipster.com/nsindexset/

2 Comments

NSIndexSet represents just a set of indices. You cannot use it to store the order of elements.
nsindexset isnt ordered - I wish there was an NSOrderedIndexSet :(

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.