How to use NSEnumerator with NSMutableDictionary? - iphone

How do I use NSEnumerator with NSMutableDictionary, to print out all the keys and values?
Thanks!

Unless you need to use NSEnumerator, you can use fast enumeration (which is faster) and concise.
for(NSString *aKey in myDictionary) {
NSLog(#"%#", aKey);
NSLog(#"%#", [[myDictionary valueForKey:aKey] string]); //made up method
}
Also you can use an Enumerator with fast enumeration:
NSEnumerator *enumerator = [myDictionary keyEnumerator];
for(NSString *aKey in enumerator) {
NSLog(#"%#", aKey);
NSLog(#"%#", [[myDictionary valueForKey:aKey] string]); //made up method
}
This is useful for things like doing the reverse enumerator in an array.

From the NSDictionary class reference:
You can enumerate the contents of a dictionary by key or by value using the NSEnumerator object returned by keyEnumerator and objectEnumerator respectively.
In other words:
NSEnumerator *enumerator = [myMutableDict keyEnumerator];
id aKey = nil;
while ( (aKey = [enumerator nextObject]) != nil) {
id value = [myMutableDict objectForKey:anObject];
NSLog(#"%#: %#", aKey, value);
}

Here is the version without object search. Notice that objectForKey calling not exist.
They use keyEnumerator and objectEnumerator both.
id aKey = nil;
NSEnumerator *keyEnumerator = [paramaters keyEnumerator];
NSEnumerator *objectEnumerator = [paramaters objectEnumerator];
while ( (aKey = [keyEnumerator nextObject]) != nil) {
id value = [objectEnumerator nextObject];
NSLog(#"%#: %#", aKey, value);
}

Related

How to store multi-type data in NSArray?

NSArray *pets = [NSArray arrayWithObjects:#"Cat", #"Dog", #"Rat", nil];
// how do I store int value 456 in this array after #"Rat" object, + pet is of type NSString so will not it generate error in while loop...??? so what data-type should i use for pet pointer that can represent all nextObject values/objects
NSEnumerator *enumerator = [pets objectEnumerator];
NSString *pet;
while (pet = [enumerator nextObject]) {
NSLog(#"Pet: %#", pet);
}
Since NSArray will only hold object you can not add an integer, you will need to wrap it in a NSNumber.
NSArray *pets = #[#"Cat", #"Dog", #"Rat", #456];
This will work with the loop you have in your example, but if you want to call any NSString method you will need to check the type:
for(id pet in pets) {
if(![pet isKindOfClass:[NSString class]) {
// It not a string, just continue to the next object.
continue;
}
}
Or a while loop:
id pet;
NSEnumerator *enumerator = [pets objectEnumerator];
while (pet = [enumerator nextObject]) {
if(![pet isKindOfClass:[NSString class]) {
// It not a string, just continue to the next object.
continue;
}
}
Use #456, it's the same as [NSNumber numberWithInt:456]
Use id. i.e.:
id pet;
while (pet = [enumerator nextObject]) {
NSLog(#"Pet: %#", pet); // maybe unsafe if only a subset of the objects in the array can execute the methods
// if you want to unwrap the pet to the concrete class, cast it with (NSString *)pet
// but make sure the object is of correct type
if ([pet isKindOfClass: [NSString class]]) {// use isMemberOfClass for exactly this class and isKindOfClasses for this class and subclasses of it
// here you are sure it is a NSString
}
}

Creating an Array of values from an Array of Dictionaries

The question sounds weird but I'm getting an array of dictionaries as parsed result.
Something like this:
parsed content: (
{
"name" = "John";
"lastname" = "Doe";
"foo" = "bar";
}
What would be the suggestion for best way to create an array of values??
Like this?
- (void)flattenDictionary:(NSDictionary *)d intoKeys:(NSMutableArray *)keys andValues:(NSMutableArray *)values {
for (id key in [d allKeys]) {
[keys addObject:key];
[values addObject:[d valueForKey:key]];
}
}
- (void)flattenDictionaries:(NSArray *)arrayOfDictionaries {
NSMutableArray *keys = [NSMutableArray array];
NSMutableArray *values = [NSMutableArray array];
for (NSDictionary *d in arrayOfDictionaries) {
[self flattenDictionary intoKeys:keys andValues:values];
}
NSLog(#"now we have these values %#", values);
NSLog(#"corresponding to these keys %#", keys);
}
You can get the values with:
NSArray *values = dictionary.allValues;
Or, loop through it:
[dictionary enumerateKeysAndObjectsUsingBlock:^(id key, id object, BOOL *stop) {
    NSLog(#"%# = %#", key, object);
}];
To do that loop through them and create an array.

Convert NSMutableArray to NSDictionary in order to use objectForKey?

I have an NSMutableArray that looks like this
{
"#active" = false;
"#name" = NAME1;
},
{
"#active" = false;
"#name" = NAME2;
}
Is there a way to convert this to an NSDictionary and then use objectForKey to get an array of the name objects? How else can I get these objects?
There is a even shorter form then this proposed by Hubert
NSArray *allNames = [array valueForKey:#"name"];
valueForKey: on NSArray returns a new array by sending valueForKey:givenKey to all it elements.
From the docs:
valueForKey:
Returns an array containing the results of invoking
valueForKey: using key on each of the array's objects.
- (id)valueForKey:(NSString *)key
Parameters
key The key to retrieve.
Return Value
The value of the retrieved key.
Discussion
The returned array contains NSNull elements for each object that returns nil.
Example:
NSArray *array = #[#{ #"active": #NO,#"name": #"Alice"},
#{ #"active": #NO,#"name": #"Bob"}];
NSLog(#"%#\n%#", array, [array valueForKey:#"name"]);
result:
(
{
active = 0;
name = Alice;
},
{
active = 0;
name = Bob;
}
)
(
Alice,
Bob
)
If you want to convert NSMutableArray to corresponding NSDictionary, just simply use mutableCopy
NSMutableArray *phone_list; //your Array
NSDictionary *dictionary = [[NSDictionary alloc] init];
dictionary = [phone_list mutableCopy];
This is an Array of Dictionary objects, so to get the values you would:
[[myArray objectAtIndex:0]valueForKey:#"name"]; //Replace index with the index you want and/or the key.
This is example one of the exmple get the emplyee list NSMutableArray and create NSMutableDictionary.......
NSMutableArray *emloyees = [[NSMutableArray alloc]initWithObjects:#"saman",#"Ruchira",#"Rukshan",#"ishan",#"Harsha",#"Ghihan",#"Lakmali",#"Dasuni", nil];
NSMutableDictionary *dict = [NSMutableDictionary dictionary];
for (NSString *word in emloyees) {
NSString *firstLetter = [[word substringToIndex:1] uppercaseString];
letterList = [dict objectForKey:firstLetter];
if (!letterList) {
letterList = [NSMutableArray array];
[dict setObject:letterList forKey:firstLetter];
}
[letterList addObject:word];
} NSLog(#"dic %#",dict);
yes you can
see this example:
NSDictionary *responseDictionary = [[request responseString] JSONValue];
NSMutableArray *dict = [responseDictionary objectForKey:#"data"];
NSDictionary *entry = [dict objectAtIndex:0];
NSString *num = [entry objectForKey:#"num"];
NSString *name = [entry objectForKey:#"name"];
NSString *score = [entry objectForKey:#"score"];
im sorry if i can't elaborate much because i am also working on something
but i hope that can help you. :)
No, guys.... the problem is that you are stepping on the KeyValue Mechanism in cocoa.
KeyValueCoding specifies that the #count symbol can be used in a keyPath....
myArray.#count
SOOOOOO.... just switch to the ObjectForKey and your ok!
NSMutableDictionary *myDictionary = [NSMutableDictionary dictionaryWithObjectsAndKeys:#"theValue", #"#name", nil];
id kvoReturnedObject = [myDictionary valueForKey:#"#name"]; //WON'T WORK, the # symbol is special in the valueForKey
id dictionaryReturnedObject = [myDictionary objectForKey:#"#name"];
NSLog(#"object = %#", dictionaryReturnedObject);

trying to sort data from a dictionary in a dictionary iPhone

can someone explain to me why [tweets count]; is equal to 1 please? the finalDict atm only has one dictionary, but arrayForLetter has 6 and in each of them some values. how do i get all 6 dictionaries from arrayForLetter ?
NSEnumerator *enumerator = [finalDict keyEnumerator];
id key;
while ((key = [enumerator nextObject])) {
NSDictionary *arrayForLetter = [finalDict objectForKey:key];
NSLog(#"arrayForLetter %#",arrayForLetter);
NSEnumerator *myEnumerator = [arrayForLetter keyEnumerator];
id myKey;
while ((myKey = [myEnumerator nextObject])) {
statuses=[[arrayResults alloc] initWithAppDictionary:arrayForLetter andAppID:myKey];
tweets = [[NSMutableArray alloc] init] ;
[tweets addObject:statuses];
[countryList reloadData];
//NSLog(#"%# : %#", key, [finalDict objectForKey:key]);
}
}
The reason is obvious.. within the while loop you are re-allocating the tweets array and then adding an object. To get count of 6 you need to alloc - init the tweets array before the while loop !

NSArray of many NSDictionary. What is the best way to find a NSDictionary with necessary value for given key?

Now I'm trying the following and it works.
- (void)findDictionaryWithValueForKey:(NSString *)name {
for (NSDictionary * set in myArray) {
if ([[set objectForKey:#"title"] isEqualToString:name])
\\do something
}
}
EDIT:
I've added one extra argument to the post of bshirley. Now it looks more flexible.
- (NSDictionary *)findDictionaryWithValue:(NSString*)name forKey:(NSString *)key {
__block BOOL found = NO;
__block NSDictionary *dict = nil;
[self.cardSetsArray enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
dict = (NSDictionary *)obj;
NSString *title = [dict valueForKey:key];
if ([title isEqualToString:name]) {
found = YES;
*stop = YES;
}
}];
if (found) {
return dict;
} else {
return nil;
}
}
Here's one possible implementation using newer API. (I also modified the method to actually return the value). Provided mostly to demonstrate that API. The assumption is that the title is unique to one dictionary within your array.
- (NSDictionary *)findDictionaryWithValueForKey:(NSString *)name {
// ivar: NSArray *myArray;
__block BOOL found = NO;
__block NSDictionary *dict = nil;
[myArray enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
dict = (NSDictionary *)obj;
NSString *title = [dict valueForKey:#"title"];
if ([title isEqualToString:name]) {
found = YES;
*stop = YES;
}
}];
if (found) {
return dict;
} else {
return nil;
}
}
Use filteredArrayUsingPredicate: method of the array to get all the dictionaries that satisfy your requirement.
NSPredicate * predicate = [NSPredicate predicateWithFormat:#" title MATCHES[cd] %#", name];
NSArray * matches = [myArray filteredArrayUsingPredicate:predicate];
Now matches is the array of dictionaries that have the title key equal to name.
- (void)findDictionaryWithValueForKey:(NSString)name {
for (NSDictionary * set in myArray) {
NSString *s=[NSString stringWithFormat:#"%#",[set objectForKey:#"title"]];
if ([s isEqualToString:name])
\\do something
}
OR
if (s == name])
\\do something
}
}
I will also suggest this way,it would be better if you use a break statement,
- (void)findDictionaryWithValueForKey:(NSString)name {
for (NSDictionary * set in myArray) {
if ([[set objectForKey:#"title"] isEqualToString:name])
\\do something
break;
}
}
As per the NSArray documentation,
valueForKey:
Returns an array containing the results of invoking valueForKey: using key on each of the array's objects.
- (id)valueForKey:(NSString *)key
Parameters
key
The key to retrieve.
Return Value
The value of the retrieved key.
Discussion
The returned array contains NSNull elements for each object that returns nil.
Availability
* Available in Mac OS X v10.3 and later.
EDIT:
try this,
[myArray valueForKey:#"name"];
//this will return array of values, but this actually differ from what to want