max_
max_

Reputation: 24481

NSMutableArray sorting returning incorrect order

I am attempting to sort an NSMutableArray depending on the distance between two locations (the current location, and specified coordinates in the first for loop). However, the sort isn't returning any specific order, but instead a completely random order (see the pic here: http://u.maxk.me/iz7Z).

Please can you tell me where I am going wrong?

Sorting:

[self.venues sortUsingComparator:^NSComparisonResult(id obj1, id obj2) {

    return [[obj1 objectForKey:@"distance"] compare:[obj2 objectForKey:@"distance"]];

}];

-setVenues:

- (void) setVenues:(NSMutableArray *)_venues {

    if (venues != _venues) {

        [venues release];

        ...

        NSMutableArray *updatedVenues = [NSMutableArray array];            

        for (NSDictionary *venue in _venues) {

            ...

            if (address != nil && city != nil) {

                CLLocationCoordinate2D coord = CLLocationCoordinate2DMake([[_location objectForKey:@"lat"] floatValue], [[_location objectForKey:@"lng"] floatValue]);

                CLLocation *currentLoc = [[CLLocation alloc] initWithLatitude:self.currentLocation.latitude longitude:self.currentLocation.longitude];
                CLLocation *venueLoc = [[CLLocation alloc] initWithLatitude:coord.latitude longitude:coord.longitude];

                CLLocationDistance distance = [venueLoc distanceFromLocation:currentLoc];

                float miles = distance / 1000;
                miles *= 0.621371192; // metres to miles

                NSMutableDictionary *newLocation = [NSMutableDictionary dictionaryWithDictionary:_location];
                [newLocation removeObjectForKey:@"distance"];
                [newLocation setObject:[NSNumber numberWithFloat:miles] forKey:@"distance"];
                _location = [NSDictionary dictionaryWithDictionary:newLocation];

                ...

                NSMutableDictionary *newVenue = [NSMutableDictionary dictionaryWithDictionary:venue];
                [newVenue removeObjectForKey:@"location"];
                [newVenue setObject:_location forKey:@"location"];                   
                [updatedVenues addObject:newVenue];

            }

        }

        venues = [updatedVenues retain];

    }

}

Upvotes: 0

Views: 241

Answers (1)

Nathan Villaescusa
Nathan Villaescusa

Reputation: 17629

It looks like you need to sort by venue.location.distance:

[self.venues sortUsingComparator:^NSComparisonResult(id obj1, id obj2) {

    NSNumber *distance1 = [[obj1 objectForKey:@"location"] objectForKey:@"distance"];
    NSNumber *distance2 = [[obj2 objectForKey:@"location"] objectForKey:@"distance"];
    return [distance1 compare:distance2];

}];

If you are using a version of Xcode >= 4.4 (4.5 for iOS) you could just do:

[self.venues sortUsingComparator:^NSComparisonResult(id obj1, id obj2) {
    return [obj1[@"location"][@"distance"] compare:obj2[@"location"][@"distance"]];

}];

Upvotes: 3

Related Questions