I pull out an array of dictionaries directly from Parse and display them in a table. Therefore, I would really like to work with the data structure that I passed (these are strangely structured dictionaries below).
A PFObject is [String : AnyObject?] , And I want to be able to sort by any key, so I donβt know the type of object, and the key may not be in some dictionaries. Because in Parse, if you do not give a property a value, it simply does not exist. For instance:
[ { "ObjectId" : "1", "Name" : "Frank", "Age" : 32 }, { "ObjectId" : "2", "Name" : "Bill" }, { "ObjectId" : "3", "Age" : 18 } { "ObjectId" : "4", "Name" : "Susan", "Age" : 47 }
]
I want dictionaries with missing keys always to be ordered after sorted dictionaries. Example:
Original table:
ObjectId Name Age 1 Frank 32 2 Bill 3 18 4 Susan 47
Sorted by name:
ObjectId Name Age 2 Bill 1 Frank 32 4 Susan 47 3 18
Since I do not have much control over the data model, and its use is limited throughout the application, I would prefer to focus on the algorithmic solution rather than the structural one.
I came up with a way to do this, but it seems inefficient and slow, I'm sure someone can do it better.
//dataModel is an array of dictionary objects used as my table source //sort mode is NSComparisonResult ascending or descending //propertyName is the dictionary key //first filter out any objects that dont have this key let filteredFirstHalf = dataModel.filter({ $0[propertyName] != nil }) let filteredSecondHalf = dataModel.filter({ $0[propertyName] == nil }) //sort the dictionaries that have the key let sortedAndFiltered = filteredFirstHalf { some1, some2 in if let one = some1[propertyName] as? NSDate, two = some2[propertyName] as? NSDate { return one.compare(two) == sortMode } else if let one = some1[propertyName] as? String, two = some2[propertyName] as? String { return one.compare(two) == sortMode } else if let one = some1[propertyName] as? NSNumber, two = some2[propertyName] as? NSNumber { return one.compare(two) == sortMode } else { fatalError("filteredFirstHalf shouldn't be here") } } //this will always put the blanks behind the sorted dataModel = sortedAndFiltered + filteredSecondHalf
Thanks!