Sort an array using NSSortDescriptor without use of any key?

838 views Asked by At

I have an array appd.arrOfDictAppProd, in there is a a key Price which is a String value. But i want to sort this array by Price value. So I fetch Price key from appd.arrOfDictAppProd array and convert Price to String to Int, then make an NSMutableArray newarray without any key. I want to sort this using NSSortDescriptor this without use of any Key because in my newarray have no key. My code is here:

for (int i = 0; i<appd.arrOfDictAppProd.count; i++) {
    NSString *price_Value = [[appd.arrOfDictAppProd objectAtIndex:indexPath.row] objectForKey:@"price"];
    int price_IntValue = [price_Value intValue];
    NSLog(@"int value of prices:%d",price_IntValue);

    NSNumber *num = [NSNumber  numberWithInteger:price_IntValue];
    NSLog(@"number-%@",num);
    [newarray addObject:num];

}
NSLog(@"price array:%@",newarray);

NSSortDescriptor *sortDescriptor;
sortDescriptor =[[NSSortDescriptor alloc] initWithKey:@"num"
                                                    ascending:YES];
NSArray *sortDescriptors = [NSArray arrayWithObject:sortDescriptor];
NSArray *sortedArray1;
sortedArray1 = [newarray sortedArrayUsingDescriptors:sortDescriptors];

When i run my program, in the newarray I have 14 values but these are same, that is 3.

2

There are 2 answers

0
Tommy On BEST ANSWER

Possibly I've missed the point but it sounds like you're massively overcomplicating things.

NSArray *sortedArray = [appd.arrOfDictAppProd sortedArrayUsingDescriptors:
    @[
        [NSSortDescritptor sortDescriptorWithKey:@"price.intValue" ascending:YES]
    ]];

If you wanted to create newarray regardless — or just without your manual loop — then go with:

NSArray *newarray = [appd.arrOfDictAppProd valueForKeyPath:@"price.intValue"];

The mechanism relied upon here is key-value coding. I've also built upon the specific way that NSDictionary and NSArray implement key-value coding.

-valueForKey: and -valueForKeyPath: are provided by NSObject. Ignoring special cases and fallbacks, an object will respond to the former by returning the value of that property as an object — amongst other things it'll automatically convert built-in numeric types to NSNumbers. The latter will traverse object hierarchies, as e.g. object.property1.property2 will request object, then request property1 from object, then request property2 from property1.

You can therefore use [stringObject valueForKey:@"intValue"] to access the intValue property on stringObject and then have NSObject package it up into an NSNumber.

NSDictionary has an implementation of key-value coding that will look into the dictionary for an appropriate value unless it's prefixed with an @ to mean that you want information about the dictionary, not from the dictionary. Because your key name is a string that doesn't begin with an @, valueForKey: therefore ends up calling objectForKey:.

Therefore the sort descriptor with key price.intValue on an array of dictionaries will ask each dictionary for the value for key price. The dictionary will decide to call objectForKey:. It'll get a string back. It'll call intValue on that string and get an int back. It'll then wrap that into an NSNumber and compare the numbers for all dictionaries to decide the ordering.

NSArray implements valueForKey: and valueForKeyPath: by calling the corresponding method on each item in the array in turn and then returning the array containing all those results. So you can use key-value coding as a way to map results to a certain extent.

3
Glorfindel On

Because newarray is just a (mutable) array of NSNumbers, and NSNumber implements the compare: method, you can call

[newarray sortArrayUsingComparator:@selector(compare:)];

immediately after the for-loop. You don't need sort descriptors.