0

So I have an array of custom "Element" objects (hey hold atomic number, chemical symbol, atomic mass, etc...) and I am having trouble sorting them by one of their properties;

Here is the code:

switch (sortDescriptor) {

        case 0: {
            //Sort the array by "ATOMIC NUMBER"
            NSArray *sortedArray = [self.elementsArray sortedArrayUsingComparator:^(id a, id b) {
                NSNumber *first = @([(SAMElement *)a atomicNumber]);
                NSNumber *second = @([(SAMElement *)b atomicNumber]);
                return [first compare:second];
            }];
            self.elementsArray = [sortedArray mutableCopy];
        }

        case 1: {
            //Sort the array by "ELEMENT NAME"
            NSArray *sortedArray = [self.elementsArray sortedArrayUsingComparator:^(id a, id b) {
                NSString *first = [(SAMElement *)a elementName];
                NSString *second = [(SAMElement *)b elementName];
                return [first compare:second];
            }];
            self.elementsArray = [sortedArray mutableCopy];
        }
        case 2:{
            NSLog(@"sorting by chemical symbol");
            //Sort the array by "CHEMICAL SYMBOL"
            NSArray *sortedArray = [self.elementsArray sortedArrayUsingComparator:^(id a, id b) {
                NSString *first = [(SAMElement *)a  chemichalSymbol];
                NSString *second = [(SAMElement *)b chemichalSymbol];
                return [first compare:second];
            }];
            self.elementsArray = [sortedArray mutableCopy];
        }

        case 3: {
            //Sort the array by "ATOMIC MASS"
            NSArray *sortedArray = [self.elementsArray sortedArrayUsingComparator:^(id a, id b) {
                NSNumber *first = [(SAMElement *)a atomicMass];
                NSNumber *second = [(SAMElement *)b atomicMass];
                return [first compare:second];
            }];
            self.elementsArray = [sortedArray mutableCopy];
        }
        default:
            break;
    }

When is sorts it returns a totally random list of elements. Am i doing something wrong?

3
  • Did you debug the code to veify the values of "first" and "second" attributes? Commented Aug 2, 2013 at 13:07
  • 1
    Did you intentionally left out the break; after the case blocks, so that e.g. when sortDescriptor==2 the array is first sorted by chemical symbol and then again by atomic mass? Commented Aug 2, 2013 at 15:42
  • Did any answer worked for you? If yes, please accept one in order to remove your question from Unanswered. If not, please give some feedback with new informations. Commented Aug 3, 2013 at 12:37

2 Answers 2

3

The best way to sort an array of objects by some property of the object, its using NSSortDescriptor. In initWithKey, you can set the name of the property that you want to sort.

NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"atomicNumber" ascending:NO];   
[self.elementsArray sortUsingDescriptors:@[sortDescriptor]];

In your case, just copy this code above in each case section of your switch statement, changing the key for @"elementName" and @"chemichalSymbol".

You can change the ascending value from NO to YES, depending what type of order do you want.

Please, let me know if worked or not.

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

2 Comments

Not wrong, but it's unusual to use initWithObjects:count: this way. Any reason you choose to do that rather than the simpler arrayWithObject: (or now with literals of course: @[]).
That syntax its because it was using a reference to a sortDescriptor pointer, and once its not an id object, those initializators couldn't be used. But I did a little reseach now, and did see other code without the reference operand in the sortDescriptor. I think my code was a little outdated, I looked for it a long time ago, so I edited my anwser to update with new syntax.
1

I'm not seeing the bug immediately, but you're reinventing the wheel here. The correct tool for this is sortedArrayUsingDescriptors:

[self.elementsArray sortedArrayUsingDescriptors:@[ 
                 [NSSortDescriptor alloc] initWithKey:@"atomicNumber"] ascending:YES]
                                                  ]];

Try that and see if it gets rid of your bug. If you're getting random orders, that usually suggests that your comparitor is inconsistent (sometimes A>B and sometimes B>A for the same A&B).

Comments

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.