views:

301

answers:

3

Hello,

I am parsing an XML and storing all data in NSMutableArray in form of Dictionary.

NSMutableArray * stories;   

// a temporary item; added to the "stories" array one at a time,
// and cleared for the next one
NSMutableDictionary * item;

- (void)parser:(NSXMLParser *)parser
 didEndElement:(NSString *)elementName
  namespaceURI:(NSString *)namespaceURI 
 qualifiedName:(NSString *)qName
{       
    if ([elementName isEqualToString:@"item"])
    {
        // save values to an item, then store that item into the array...
        [item setObject:currentTitle forKey:@"title"];
        [item setObject:currentLink forKey:@"link"];
        [item setObject:currentSummary forKey:@"summary"];
        [item setObject:currentDate forKey:@"date"];

        //Numeric value for sorting
        [item setObject:rates forKey:@"rates"];

        [stories addObject:[item copy]];    
    }
}

Once I am done with parsing, I need to sort array by "rates" which is numeric filed. Please suggest.

A: 

If you want to sort an array of dictionaries by an arbitrary dictionary key, then I think what you want to use is NSArray sortedArrayUsingFunction:context: with a comparison function that looks up and compares the keys you want to sort by. Check out the documentation on that.

Otherwise you'll need to define a class to replace your dictionary and define a comparison method in that class, then use sortedArrayUsingSelector:

Nimrod
You should read up on NSSortDescriptor: http://developer.apple.com/mac/library/documentation/Cocoa/Reference/Foundation/Classes/NSSortDescriptor_Class/
Peter Hosey
A: 

If you have an array of objects (could be applied to dictionaries), each object (A) contains first name, last name, age and you want to sort on age:

NSMutableArray * array = [NSMutableArray array];
[array addObject:[A aWithFirstName:@"John"
                          lastName:@"Blay"
                               age:[NSNumber numberWithInt:30]]];
[array addObject:[A aWithFirstName:@"John"
                          lastName:@"Albort"
                               age:[NSNumber numberWithInt:15]]];
[array addObject:[A aWithFirstName:@"Axel" 
                          lastName:@"Albort" 
                               age:[NSNumber numberWithInt:40]]];
[array addObject:[A aWithFirstName:@"Peter"
                          lastName:@"Albort" 
                               age:[NSNumber numberWithInt:20]]];
[array addObject:[A aWithFirstName:@"Kevin"
                          lastName:@"Klein" 
                               age:[NSNumber numberWithInt:20]]];
// create sort descriptor
NSSortDescriptor * ageDescriptor = 
    [[[NSSortDescriptor alloc] initWithKey:@"age"
                                ascending:YES] autorelease];
NSArray * descriptors;
NSArray * sortedArray;
// array of sort descriptor - could use multiple descriptors for sorting
descriptors = [NSArray arrayWithObjects:ageDescriptor, nil];
// sort data
sortedArray = [array sortedArrayUsingDescriptors:descriptors];
// print out sorted data
id obj;
NSEnumerator * enumerator;
enumerator = [sortedArray objectEnumerator];
while ((obj = [enumerator nextObject])) NSLog(@"%@", obj);

Output (sorted on age):

2010-01-09 22:14:38.391 x[38860:903] Albort, John; age 15
2010-01-09 22:14:38.391 x[38860:903] Albort, Peter; age 20
2010-01-09 22:14:38.392 x[38860:903] Klein, Kevin; age 20
2010-01-09 22:14:38.393 x[38860:903] Blay, John; age 30
2010-01-09 22:14:38.393 x[38860:903] Albort, Axel; age 40

It works the same if instead of my class A you use NSDictonary.

stefanB
+4  A: 

Assuming that rates key holds NSNumbers:

NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey: @"rates" ascending: YES];
[stories sortUsingDescriptors: [NSArray arrayWithObject: sortDescriptor]];
[sortDescriptor release];

On a related note, this line of code has a leak:

[stories addObject:[item copy]];

I think you meant this instead:

[stories addObject:[[item copy] autorelease]];
Costique
stefanB: “no need for autorelease” Incorrect. The questioner must send `autorelease` or `release` sooner or later to balance out the `copy`. And the `copy` is necessary because otherwise he would be adding the same (mutable) dictionary N times.
Peter Hosey
I dont know about above comments, what i Know is "This has worked for me" :D
iPhoneDev