I have a NSDictionary with currency-codes as keys and as values another NSDictionary inside containing a NSString (currency name) + a NSArray (list of coins):
The goal is to get a NSArray with currency-keys (AED, ARS, ...), sorted by name-value inside.
I know how to sort by keys and values, but can't figure out how to sort by the a value inside a NSDictionary inside a NSDictionary.
The following only gives me a sorted NSArray with the values, but I loose the keys:
NSMutableArray *dictValues = [[self.currencyDict allValues] mutableCopy];
[dictValues sortUsingComparator: (NSComparator)^(NSDictionary *a, NSDictionary *b)
{
NSString *key1 = [a objectForKey: #"name"];
NSString *key2 = [b objectForKey: #"name"];
return [key1 compare: key2];
}
];
In order to convert a dictionary of dictionaries into an array of dictionaries without losing the key, the first step is to put the key into the dictionary. In other words, you need to convert this
Root
AED
name "some name"
objects ...
ARS
name "other name"
objects ...
to this
Root
AED
name "some name"
objects ...
key "AED"
ARS
name "other name"
objects ...
key "ARS"
and then call allValues and sort the resulting array.
Related
I wrote a method that takes in parameter a SQL requests (SELECT name FROM table) and return a NSDictionnary with first letter of word as key
Dictionnary
{
A = ("Arbre", "Armoise");
B = ("Bob", "Bill") ;
...
}
So I'm stuck with that, Now if my request look like SELECT name_en FROM table WHERE name_fr LIKE "Bob"
My dictionnary will look like :
Dic {
B = ("Bob");
}
And I just want to display Bob. So How can I get this value ? I already tried objectAtIndex and [[dic allKeys] objectAtIndex:0];
But I got nothing
Thanks !
There is no such thing as the "first object" in a dictionary. A dictionary is an unordered collection.
I'm not 100% certain what you're asking but what you could do is take the array of keys...
NSArray *keys = [dictionary allKeys];
and then sort the array
NSArray *sortedKeys = [keys sortedArrayUsing... // choose your own method for sorting
Then get the object related to the first sorted key...
id firstObject = dictionary[[sortedKeys firstObject]];
I have an NSArray of NSDictionaries.
The dictionaries has keys like this: color, number, code, description and size.
Now I have a key and I want to locate that dictionary inside the array, some magic command like:
NSDictionary *oneDict = [get a dictionary from myArray where "code" is equal to "32"];
code is a key, 32 a value.
I know how to enumerate the array and search one by one every dict, but I know objective-c is a bag full of "tricks" and a "magic command" may exist to extract surgically this dictionary from the array in one line.
Any clues?
You can use indexOfObjectPassingTest to get the object index:
NSUInteger index = [myArray indexOfObjectPassingTest:^BOOL(id obj, NSUInteger idx, BOOL *stop) {
NSDictionary* dict = obj;
return [obj[#"code"] intValue] == 32;
}];
If not found, result will be NSNotFound;
This can be done with an NSPredicate simpler:
NSPredicate * predicate = [NSPredicate predicateWithFormat:#"code MATCHES[cd] %#", value];
NSArray *result = [myArray filteredArrayUsingPredicate:predicate];
The result array will hold all NSDictionaries that did match the value.
Take a look at the NSPredicate documentation
It is very powerful
If you intend to do the lookup many times and don't mind spending some time on setup, you could create a dictionary that maps the values of code to the dictionaries that contain those values. i.e.:
NSDictionary * mapping = [ NSDictionary dictionaryWithObjects:myArray forKeys:[ myArray valueForKey:#"code" ] ]
id answer = mapping[#"32" ] ;
This only works if code contains unique values. If the values are not unique:
NSArray * codeValues = [ myArray valueForKey:#"code" ] ;
NSIndexSet indexes = [ codeValues indexesOfObjectsPassingTest:^BOOL(id object){ [ object isEqual:#"32" ] } ] ;
NSArray * matchingDictionaries = [ myArray objectsAtIndexes:indexes ] ;
matchingDictionaries will be an array containing dictionaries where code is #"32".
Replace #"32" in these examples with the value of code you wish to find, &c.
I have an NSMutableArray of many NSDictionaries that contain keys like "Title". In some cases there are duplicates of dictionaries with the same "Title" but differences in the other keys.
How can I remove the dictionaries that have the same "Title" key and leave only one in the array?
Thanks
Sort the array using NSSortDescriptor on the key path 'title'. Next, loop over the array and build a new array:
NSString *lastTitle = nil;
NSMutableArray *result = [NSMutableArray array];
for (NSDictionary *d in array) {
NSString *testTitle = [d objectForKey:#"title"];
if (![testTitle isEqualToString:lastTitle]) {
[result addObject:d];
lastTitle = testTitle;
}
}
Now result contains your filtered list.
It's important to sort the array first for this algorithm to work.
I have a dictionary with key-value pair populated from JSON returned data.What I wish to do is use the dictionary to populate UITableView.
I have this structure for table:
[Product Name]
By [Manufacturer Name]
What this means is that key is Product Name and Value is Manufacturer Name. I need to get the name of the key and the name of the value. How can this be done? and is it possible without for-loop?
I'd use the enumerateKeysAndObjectsUsingBlock: method. The following code builds a list of the strings you require.
NSMutableArray *names = [NSMutableArray array];
[dictionary enumerateKeysAndObjectsUsingBlock: ^(NSString *key, NSString *object, BOOL *stop) {
[names addObject[NSString stringWithFormat:#"%# By %#",key, object]];
}];
You can use the keyEnumerator of NSDictionary and for each key look up the value. This could look something like this:
for (NSString *p in dict)
{
NSString *m = [dict objectForKey:p];
// do something with (p,m)
}
You should not be concerned with avoiding for-loops. After all, something like a for loop will always happen somewhere underneath.
If your keys are dynamic from json then you can use
NSArray *keys = [dictionary allkeys];
Then in the table View Cell for row at index path method you can populate the table view with the corresponding keys and their values.
NSArray * keys = [results allKeys];
for (int i = 0;i<[keys count];c++){
NSString* productName = [key objectAtIndex:i];
NSString* manufacturerName = [results objectForKey:productName];
}
Hope this helps...
I have assumed the name as strings, you can change the type according to your situation..
I call an URL that returns me JSON (I use JSONKit). I convert it to a NSString that is this way:
[{"name":"aaaaaa","id":41},{"name":"as","id":23},...
And so on. I want to fill an UIPickerView with only the "name" part of the JSON. But, when the user selects a name, i need the "id" parameter, so i've thought to fill a NSDictionary with the JSON (setValue:id for key:name), so i can get the value picked by the user, and get the id from the dictionary. how could I fill an array with only the "name" of the JSON?
Im a bit lost with the JSONKit library, any guidance? Thank you.
First of all I don't think that its a good idea to have name as key in a dictionary, since you can have many identical names. I would go for id as key.
Now, what you could do is:
NSString *myJson; //Suppose that this is the json you have fetched from the url
id jsonObject = [myJson objectFromJSONString];
// Now you have an array of dictionaries
// each one having 2 key/value pairs (name/id)
NSArray *names = [jsonObject valueForKeyPath:#"name"];
NSArray *ids = [jsonObject valueForKeyPath:#"id"];
// Now you have two parallel arrays with names / ids
Or you could just iterate your json object and handle the data yourself:
for (id obj in jsonObject)
{
NSString *name = [obj valueForKey:#"name"];
NSNumber *id = [obj valueForKey:#"id"];
// Do whatever you like with these
}