z22
z22

Reputation: 10083

iOS Sort array based on float value

I wish to sort an array data based on height parameter which is in float. I used NSSortDescriptor but it isn't working.

Following is my code:

NSSortDescriptor *hDescriptor = [[NSSortDescriptor alloc] initWithKey:@"Height" ascending:YES];

NSArray *sortDescriptors = @[hDescriptor];

[[[appDelegate.arr objectAtIndex:section] objectForKey:@"arrPerson"] sortedArrayUsingDescriptors:sortDescriptors];
NSLog(@"%@",[[appDelegate.arr objectAtIndex:section] objectForKey:@"arrPerson"]); // height is printed in random order. not sorted

How do I solve this?

edited: log

(
    {
    Height = "11.5766";
    Name = "abc";
},
    {
    Height = "11.8443";
    Name = "sdfsdf";
},
    {
    Height = "12.211";
    Name = "hnkhjk";
},
    {
    Height = "13.7271";
   Name = "ertert";
},
    {
    Height = "15.2694";
    Name = "sdf";
},
    {
    Height = "21.9242";
    Name = "fgh";
},
    {
    Height = "23.0857";
    Name = "ert";
},
    {
    Height = "6.48365";
    Name = "cvb";
},
    {
    Height = "7.5204";
    Name = "rt";
},
    {
    Height = "8.67856";
    Name = "asd";
}

)

Upvotes: 0

Views: 805

Answers (2)

Rich
Rich

Reputation: 8202

-sortedArrayUsingDescriptors:sortDescriptors: returns the sorted array. So you are basically just sorting it and discarding the result.

You need to sort and assign this value to the NSDictionary you are pulling it out of.

NSArray *persons = [[appDelegate.arr objectAtIndex:section] objectForKey:@"arrPerson"];
NSArray *sortedPersons = [persons sortedArrayUsingDescriptors:sortDescriptors];
[[appDelegate.arr objectAtIndex:section] setObject:sortedPersons forKey:@"arrPerson"];

But to do that you need to have a NSMutableDictionary. If you post more code in your question it might help. But the above is your problem :)

EDIT: As per discussion in the comments the values are stored as NSStrings

The following will try to convert any strings as numbers (and any other types):

NSArray *sorters = @[[NSSortDescriptor sortDescriptorWithKey:@"Height" ascending:YES comparator:^(id obj1, id obj2) {
        NSNumber *n1;
        NSNumber *n2;
        // Either use obj1/2 as numbers or try to convert them to numbers
        if ([obj1 isKindOfClass:[NSNumber class]]) {
            n1 = obj1;
        } else {
            n1 = @([[NSString stringWithFormat:@"%@", obj1] doubleValue]);
        }
        if ([obj2 isKindOfClass:[NSNumber class]]) {
            n2 = obj2;
        } else {
            n2 = @([[NSString stringWithFormat:@"%@", obj2] doubleValue]);
        }
        return [n1 compare:n2];
    }]];

NSArray *persons = [[appDelegate.arr objectAtIndex:section] objectForKey:@"arrPerson"];
NSArray *sortedPersons = [persons sortedArrayUsingDescriptors:sorters];
[[appDelegate.arr objectAtIndex:section] setObject:sortedPersons forKey:@"arrPerson"];

If you can guarantee that the Height value will always be an NSString or NSNumber (and not a NSNull if we're dealing with JSON) the following sort descriptor would also work:

NSArray *sorters = @[[NSSortDescriptor sortDescriptorWithKey:@"Height.doubleValue" ascending:YES]];

While the first sort descriptor is a bit longer, its also far more robust in case any other objects are put inside of the Height value as then you would get a class is not key value coding-compliant for the key length error.

Upvotes: 1

user3300454
user3300454

Reputation:

Try this it may work.

NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"Height"
                                                               ascending:YES];
NSArray *sortDescriptors = [NSArray arrayWithObject:sortDescriptor];
NSArray *sortedArray = [[[appDelegate.arr objectAtIndex:section] objectForKey:@"arrPerson"]sortedArrayUsingDescriptor:sortDescriptors];

Upvotes: 1

Related Questions