Join the Stack Overflow Community
Stack Overflow is a community of 6.3 million programmers, just like you, helping each other.
Join them; it only takes a minute:
Sign up

I have an iOS app with a NSMutableArray which contains many rows worth of data (split up into 3 segments) - as shown below:

[PFUser object, stringData, floatValue]
       .             .          4.3
       .             .          5.9
       .             .          1.1
       .             .          9.32
       .             .          0.024

The above diagram shows how the array is split up and the data types that are stored in the array. But those data types are not keys or anything. So I can't do something like valueForKey.

An example of what the array looks like:

@[@[userObject, @"hello", @234.1441],
  @[userObject, @"sdfsg", @94.33],
  @[userObject, @"wrfdo", @24.897]
];

So from the example above you can see that I have arrays in arrays.

I would like to sort the array by reading the 3 segment which contains the float values.

How can I do this? I have looked online and read a lot about using NSSortDescriptor but the problem I have is that all the examples always seem to use simple strings or an array with numbers only.

Is there a way to use NSSortDescriptor in an array with custom objects like mine?

share|improve this question
    
I am certain that cannot be done in a clean way. Because you will violate the sorting invariants all the time. create a custom class to store the connected data. – luk2302 Jan 7 at 21:33
2  
To be clear, you have an array of arrays where each array has 3 values, correct? The example you posted is missing commas after each inner array. – rmaddy Jan 7 at 21:35
    
@rmaddy Yes that is correct. – Supertecnoboff Jan 7 at 21:35
up vote 4 down vote accepted

You can use sortUsingComparator:

[array sortUsingComparator:^(id obj1, id obj2) {
    NSArray *arr1 = obj1;
    NSArray *arr2 = obj2;
    return [arr1[2] compare:arr2[2]];
}];

Or even (thanks to rmaddy's suggestion):

[array sortUsingComparator:^(NSArray *arr1, NSArray *arr2) {
    return [arr1[2] compare:arr2[2]];
}];

If you have a immutable array, you can use sortedArrayUsingComparator:

share|improve this answer
    
This works perfectly!!!! Thank you so much! – Supertecnoboff Jan 7 at 21:42
2  
This can be made even easier by changing the type of obj1 and obj2 to NSArray * from id. Then the body can be one line. – rmaddy Jan 7 at 21:43
    
Hmm... very good point, thanks for the suggestion :) – Cristik Jan 7 at 21:45
    
For questions "How do I sort..." the correct answer is always either "use sortUsingComparator and write the code" or "no, you can't sort dictionaries" :-) – gnasher729 Jan 8 at 9:08
    
@gnasher729 true :)) – Cristik Jan 8 at 11:56

Try this :

For example in your case to sort the array by float value :

NSMutableArray *array = // Init your array;

array = [NSMutableArray arrayWithArray:[array sortedArrayUsingComparator:^(id obj1, id obj2) {
    float value1 = [[obj1 objectAtIndex:2] floatValue];
    float value2 = [[obj2 objectAtIndex:2] floatValue];

    if (value1 < value2) {
        return (NSComparisonResult)NSOrderedDescending;
    } else if (value1 > value2) {
        return (NSComparisonResult)NSOrderedAscending;
    } else {
        return (NSComparisonResult)NSOrderedSame;
    }
}]];

With this method you can sort as you like.

share|improve this answer
    
1) Why create the mutable array? 2) Why bother with the float values? Just get each NSNumber from index 2 and compare those two objects directly. No need for the if/else. – rmaddy Jan 7 at 21:37
    
See the answer by Cristik for what I meant. It's must simpler. – rmaddy Jan 7 at 21:38
    
sortUsingComparitor: is definitely the thing, but why not just return [obj1[2] compare:obj2[2]]? – Tommy Jan 7 at 21:38
    
I create a mutable array because sortedArrayUsingComparator return an array. It is an example with float the code must be adjust. I added the if / else to compare any object with any object, for example sort by string and float. – Pipiks Jan 8 at 8:25
    
"the code must be adjust" - nonsense. You have NSNumber. NSNumber knows perfectly fine how to compare with another NSNumber. – gnasher729 Jan 8 at 9:10

NSMutableArray has a call sortUsingComparator, which takes a comparison result block as parameter. So Something like this:

[users sortUsingComparator:
     ^NSComparisonResult(id obj1, id obj2)
     {
         PFUser* userA = (PFUser*)obj1;
         PFUser* userB = (PFUser*)obj2;

        return [userA.floatValue compare:userB.floatValue];

     }];
share|improve this answer
    
This won't work. It's not an array of PFUser objects. – rmaddy Jan 7 at 21:35
    
Who ever upvoted this doesn't understand the question. This answer won't work. – rmaddy Jan 7 at 21:40

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.