Applying a sort to NSArray of custom objects - iphone

I have an array of custom objects (really an NSSet stored in Core Data which becomes an NSArray with AllObjects) and each of these custom objects is a ListItem. Each ListItem belongs to a List, which has a uniqueID. Each ListItem has a different uniqueID which is the uniqueID of the List it belongs to + a number. So if the id of my List object is #"foo", then its ListItems would each have the property ListItem1.id = #"foo0", ListItem2.id = #"foo1", ListItem3.id = "foo2" etc..
So, how can I sort my array of custom objects based on the number that is appended to this uniqueID on each ListItem?

NSArray *sortedArray = [unsortedArray sortedArrayUsingComparator:^(ListItem *obj1, ListItem *obj2){
return [obj1.id compare:obj2.id];
}];

Related

JSONKit: how to keep order of JSON dictionary keys

I've some JSON String that represents a Map (Dictionary) from the server.
I need to draw this map as it is # my iPhone app.
I am using JSONKit and it seems that it uses Hashing function to insert keys into its internal JKDictionary....
So should I send a priority number to order the keys? Or there is some way to make JSONKit to preserve keys ordering of the server JSON data?
You can choose to add a order property to your dictionary. And sort your keys using that property. Then you can enumerate your dictionary using your sorted keys. enumerateKeysAndObjectsUsingBlock:
// Here I suppose you have added another number property `order` for your dictionary's values
NSArray *sortedKeys = [dic keysSortedByValueUsingComparator:^(id obj1, id obj2){
return [obj1 order] < [obj2 order];
}];
// for in will give your an ordered travel for your sortedKeys
for (id key in sortedKeys) {
// handle your dic
[dic objectForKey:key];
}
Dictionaries are not ordered, but arrays are, so if you can change your JSON data structure to an array, you should get an ordered result.
[{'key1':'value1'},{'key2':'value2'},{'key3':'value3'}]
What does your data look like?

NSArray filteredArrayUsingPredicate: contains in other NSArray with custom key path

I have 2 NSArrays with each containing custom objects:
NSArrayToFilter
NSArrayUsedForFiltering
I want to filter my first array with a predicate that uses my second array. I want to return all the custom objects from my NSArrayToFilter where an attribute is not available in an other attribute from the custom objects in my NSArrayUsedForFiltering.
This is some pseudo-code for what I want to achieve:
[NSArrayToFilter filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:#"NOT self.attribute IN %#.attribute", NSArrayUsedForFiltering]

Table View with Countries / States / Cities

I am downloading some information from a JSON feed about countries, states and their cities. The way I have my final data structure is as follows:
An NSArray where each element holds an NSDictionary. Each NSDictionary has a key of the name of the country, and a value of an NSDictionary corresponding to the states. Each of those NSDictionarys hold a key of the name of the state and a value of an array with a list of the names of the cities.
I want to display each country in a different section in a table view. To return the number of countries (aka. numbeber of sections), I can just do [countriesArray count].
However, to return the number of states and cities of each country, that seems impossible with my current structure. I can access [countriesArray objectAtIndex:index], but after that, how can I access the value of that dictionary (the key is the name of the country)?
Should I restructure my data structures? If so, what's the best way to sort this kind of data?
you may handle this problem using the collapsible tableview
from this you can display the relevant data as your requirement.
You can have below data structure which may help.
A container NSArray which has NSDictionary as its object.
Each dictionary has fixed keys like: countryName and stateInfo.
The value of this keys will be: string and NSDictionary.
Each stateInfo dictionary should have fixed keys like: stateName, cities
the value of this keys will be: string and NSarray of cities.
NSArray *countryKeys = [countriesArray allKeys]; //will return you an array of all keys(country names).
Also, instead of doing [countriesArray objectAtIndex:index], you should do [countriesArray valueForKey:[countryKeys objectAtIndex:index]];

How to sort an NSArray of objects using another NSArray which contains the ordered keys of objects?

for example, if I have an object:
#interface MyObject
{
__id;
__data;
}
and I have an NSArray of such object:
id=4
data=Apple
id=5
data=Banana
id=6
data=Orange
I also have an NSArray of ids:
{"5", "4", "6"}
now I want to sort the array of objects by ids to be in the order in the second array, so the result should be:
id=5
data=Banana
id=4
data=Apple
id=6
data=Orange
Is it possible(in ObjC for iPhone)? What is the most efficient way?
Thanks!
You can use - (NSArray *)sortedArrayUsingComparator:(NSComparator)cmptr function of the NSArray class.
You should write your own comparator block that will return ordering depending on the position of id in the ids array - ie return NSOrderedAscending when idA is further from the start of the array than idB.
Hope this helps.

Use NSPredicates/KVC to grab an array of sibling keys

Another way to word this might be...
NSPredicate "state.country == 'United States'"
is like
SQL "Select * from state where state.country = 'United States'
so how do I do this as a predicate?
SQL "Select state.name from state where state.county = 'United States'"
ORIGINAL POST:
I have a dictionary of arrays of dictionaries that looks like this:
lists
states
state
country
country
country
I have code to filter states by country. However, I'm betting there is a cleaner way.
NSArray *states = [lists valueForKey:#"states"];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"countryname == %#", selectedCountry];
states = [states filteredArrayUsingPredicate:predicate];
states = [states valueForKeyPath:#"state"];
Ideas?
You've almost got it:
NSDictionary * lists = ...;
This is your original dictionaryl
NSArray *states = [lists objectForKey:#"states"];
This is to retrieve the array of states from your dictionary. Presumably these are actual "State" objects (ie, you made a class called State)
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"countryname == %#", selectedCountry];
This creates a predicate that will compare the results of -[State countryname] to the value referenced by the selectedCountry variable. Alternatively, if the states array contains dictionaries, this will compare the results of -[NSDictionary objectForKey:#"countryname"] to the value referenced by selectedCountry.
states = [states filteredArrayUsingPredicate:predicate];
This will retrieve all the states from the array where [[aState countryname] isEqual:selectedCountry]
states = [states valueForKeyPath:#"name"];
This will create a new array that contains the name of each state. This new array will be in the same order as your filtered states array.
I'm only using NSArray and not NSDictionary so I don't know how useful this is but I'm using this:
matchingTour = [self.tours filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:#"tourCode == %#", tourCode]];
where self.tours is an NSArray of Tour objects. A Tour object has a property of NSString *tourCode. matchingTour is of type NSArray.
I was amazed when I read about this, tried it and it worked first time and I got back an array containing just the one tour!
In your 'tree' you don't show any property name 'countryname' - just wondering.