Enumerating all the Keys and Values - ios

From API, I am able to get below format.
{
"status": true,
"data": {
"29": "Hardik sheth",
"30": "Kavit Gosvami"
}
}
In that, I want to fetch Key and value both.
How can i do this using NSDictionary?

Sometime, you need to iterate over all the key/value pairs in a dictionary. To do this, you use the method -allKeys to retrieve an array of all the keys in the dictionary; this array contains all the keys, in no particular (ie random) order. You can then cycle over this array, and for each key retrieve its value. The following example prints out all the key-values in a dictionary:
void
describeDictionary (NSDictionary *dict)
{
NSArray *keys;
int i, count;
id key, value;
keys = [dict allKeys];
count = [keys count];
for (i = 0; i < count; i++)
{
key = [keys objectAtIndex: i];
value = [dict objectForKey: key];
NSLog (#"Key: %# for value: %#", key, value);
}
}
As usual, this code is just an example of how to enumerate all the entries in a dictionary; in real life, to get a description of a NSDictionary, you just do NSLog (#"%#", myDictionary);.

Are you using Swift or Objective-C?
In Objective-C you'd use allKeys to get the list of keys, as outlined by #BhavinSolanki in his answer.
In Swift you could do that as well (using the Swift Dictionary keys property, myDictinoary.keys)
Alternately you could use tuples to loop through the keys and values:
for (key, value) in dictionary {
NSLog (#"Key: %# for value: %#", key, value);
}

Related

Loop through NSArray of objects that has no id's - Objective C

I have an NSArray that looks like the following
[{
"Id":"456",
"Type":"Dog",
"Sound":"Bark",
},
{
"Id":"789",
"Type":"Cat",
"Sound":"Meow",
}]
I tried the following
for (id key in array) { // Doesn't work
NSLog(#"%#", key[#"Type"]);
}
and I tried
NSLog(#"%#", [array firstObject]); // Doesn't work
This doesn't work however because there is no id to access. I get an NSInvalidArgumentException for both. How would I successfully loop through the two objects that I have and print out the type?
It is a bit confusing, because you say:
I have an NSArray that looks like the following
[{
"Id":"456",
"Type":"Dog",
"Sound":"Bark",
},
{
"Id":"789",
"Type":"Cat",
"Sound":"Meow",
}]
but then, you also say:
NSLog(#"%#", [array firstObject]); // Doesn't work
Of course, you don't indicate what "Doesn't work" means... Does it throw an error? Does it output nothing? Does it output something, but not what you expect?
However, if you did have an array that "looks like that", then let's see what it actually is...
We can think of a Dictionary as:
{ key1:value1, key2:value2, key3:value3, etc... }
and we can think of an Array as:
[object1, object2, object3, etc...]
So, assuming your example data is structured like that in a valid NSArray, that means you have an Array of 2 Dictionary objects. If you want to output them to the console, you can do:
// log the first object in the array
NSLog(#"%#", [array firstObject]);
and the output should be a Dictionary:
{
Id = 456;
Sound = Bark;
Type = Dog;
}
You can also do:
// for each element (each Dictionary) in array, output the dictionary
for (NSDictionary *d in array) {
NSLog(#"%#", d);
}
resulting in:
...[1234:4321] {
Id = 456;
Sound = Bark;
Type = Dog;
}
...[1234:4321] {
Id = 789;
Sound = Meow;
Type = Cat;
}
and, finally:
// for each element (each Dictionary) in array
for (NSDictionary *d in array) {
// for each Key in each Dictionary
for (NSString *key in [d allKeys]) {
NSLog(#"%# - %#", key, d[key]);
}
}
which will give you:
...[1234:4321] Sound - Bark
...[1234:4321] Id - 456
...[1234:4321] Type - Dog
...[1234:4321] Sound - Meow
...[1234:4321] Id - 789
...[1234:4321] Type - Cat
Note that dictionaries are *un-ordered, so don't count on stepping through the keys in the same order each time.
Hope that makes sense. Of course, you still need to find out why you think you have a NSArray when you don't.

Objective-c NSMutableDictionary set with an array keep empty

I'm new here, but I use to read this site when I need something, but today, I can't find an answer to my question.
I'll try to explain my problem with enough details.
I need to add an array into a NSMutableDictionary at a specific key. The key added into it is correctly up, but my dictionary value keep empty. Here is my code :
dictionarySection = [[NSMutableDictionary alloc] initWithObjects:arraySectionValues forKeys:arraySectionKeys];
dictionaryClip = [[NSMutableDictionary alloc] initWithCapacity:[arraySectionKeys count]];
NSArray *tabSection = [dictionarySection allKeys];
id key,value;
for (int j=0; j<tabSection.count; j++)
{
array = [NSMutableArray array];
key = [tabSection objectAtIndex: j];
value = [dictionarySection objectForKey: key];
//NSLog (#"Key: %# for value: %#", key, value);
for (SMXMLElement *clip in [books childrenNamed:#"clip"]) {
if([[clip valueWithPath:#"categorie"] isEqualToString:value]){
[array addObject:[clip valueWithPath:#"titre"]];
}
}
NSLog(#"Test array %#",array);
[dictionaryClip setObject:array forKey:key];
[array removeAllObjects];
NSLog(#"Test dictionary %#",dictionaryClip);
}
Here the NSLog result :
2015-07-15 14:34:48.272 test[15533:390301] Test array (
"CDS : ITV Philippe Dunoyer",
"FLASH INFO NCI : crise des banques",
"Les Roussettes sont-elles dangereuses ?",
"Flash infos banques gr\U00e8ve",
"CDS : ITV Paul Langevin",
"CDS : ITV Valls",
"CDS : ITV Victor Tutugoro",
"CDS : ITV Roch Wamytan",
"NCGLAN 20",
"Flash Info : dispositif anti-d\U00e9linquance"
)
2015-07-15 14:34:48.273 test[15533:390301] key : 0
2015-07-15 14:34:48.273 test[15533:390301] Test dictionary {
0 = (
);
}
As we can see, the array is filled, the dictionary's key is correct, but the array isn't into my dictionary.
How may I suppose to fill my dictionary with this array?
Thanks a lot guy(s) for answer(s) :)
Ps : excuse my english :(
You are calling removeAllObjects: method for same instance of array which you are passing in dictionary so it objects are being removed in stored array. Try to pass that array's copy or a new instance of array with same objects.
Example:
[dictionaryClip setObject:[array copy] forKey:key];
In Objective-C arrays are reference types.
The method setObject:forKey: puts a pointer to the array into the dictionary, the array is not copied.
If you remove all objects from the array, they also disappear in the dictionary

iOS sort one array based on order of strings in another array

This is another very specific problem I am trying to solve.
I am pulling a list a twitter user accounts logged into the users settings application. This returns an array with the usernames in the correct order.
I then pass this array to this twitter API:
https://api.twitter.com/1.1/users/lookup.json
The returned array contain all the additional data I need for each user account logged in. The first array contains NSStrings (usernames), the returned array has been parsed to contain dictionaries that have a key and value for the username, name, and profile pic.
Problem now is that the order is completely different than the first array I passed.. This is expected behavior from Twitter, but it needs to be in the exact same order (I will be referencing the original index of the AccountStore which will match the first array, but not the new array of dictionaries).
How can I tell the new array to match the contained dictionaries to be the same order as the first array based on the username key?
I know this sounds confusing, so let me at least post the data to help.
Here is the first array output:
(
kbegeman,
indeedyes,
soiownabusiness,
iphonedev4me
)
Here is what the second array outputs:
(
{
image = "https://si0.twimg.com/profile_images/3518542448/3d2862eee546894a6b0600713a8de862_normal.jpeg";
name = "Kyle Begeman";
"screen_name" = kbegeman;
},
{
image = "https://si0.twimg.com/profile_images/481537542/image_normal.jpg";
name = "Jane Doe";
"screen_name" = iPhoneDev4Me;
},
{
image = "https://twimg0-a.akamaihd.net/profile_images/378800000139973355/787498ff5a80a5f45e234b79005f56b5_normal.jpeg";
name = "John Doe";
"screen_name" = indeedyes;
},
{
image = "https://si0.twimg.com/sticky/default_profile_images/default_profile_5_normal.png";
name = "Brad Pitt";
"screen_name" = soiownabusiness;
}
)
Due to the way Twitter returns the data, it is never the EXACT same order, so I have to check this every time I call these methods.
Any help would be great, would save my night. Thanks in advance!
You want the array of dictionaries be sorted by comparing screen_name value with your first array. Right? Also, the screen name may have different case than your username. Right?
I would use mapping dictionary:
Create dictionary from screen name to user dictionary:
NSArray *screenNames = [arrayOfUserDicts valueForKeyPath:#"screen_name.lowercaseString"];
NSDictionary *userDictsByScreenName = [NSDictionary dictionaryWithObjects:arrayOfUserDicts forKeys:screenNames];
Build final array by finding user dictionary for usernames in your array:
NSMutableArray *sortedUserDicts = [NSMutableArray arrayWithCapacity:arrayOfUsernames.count];
for (NSString *username in arrayOfUsernames) {
NSDictionary *userDict = [userDictsByScreenName objectForKey:username.lowercaseString];
[sortedUserDicts addObject:userDict];
}
First generate a mapping that maps the "screen_name" to the corresponding dictionary
in the second array:
NSDictionary *map = [NSDictionary dictionaryWithObjects:secondArray
forKeys:[secondArray valueForKey:#"screen_name"]];
Then you can create the sorted array with a single loop:
NSMutableArray *sorted = [NSMutableArray array];
for (NSString *name in firstArray) {
[sorted addObject:map[name]];
}
That sort order isn't something that could be easily replicated (i.e. it's not alpha, etc). Instead, you should just use that original NSArray as a guide to match data from the NSDictionary from Twitter. For example:
[twitterDictionary enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
NSInteger index = [yourLocalArray indexOfObject:obj];
if (index != NSNotFound) {
// You have a match, do something.
}
}];
lets name your arrays as firstArray and secondArray.
NSArray *sortedArray = [secondArray sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) {
return [#([firstArray indexOfObject:[obj1 objectForKey:#"name"]]) compare:#([firstArray indexOfObject:[obj2 objectForKey:#"name"]])];
}];

iOS filter array of dictionary base on value and not the key

I have array with dictionaries like this:
Array: (
{
customerUS= {
DisplayName = "level";
InternalName = "Number 2";
NumberValue = 1;
},
customerCAN= {
DisplayName = "PurchaseAmount";
InternalName = "Number 1";
NumberValue = 3500;
};
}
)
I want to filter the dictionaries base on particular value and not the key. For example I want all the dictionaries with values on any key of 3500. Does any body knows how can I do this?
I'll really appreciate your help.
Try a predicate format like:
#"%# IN SELF", testValue
When you filter the array each will be run against the IN. When you pass IN a dictionary it uses the values of the dictionary.
you can also use
-keysOfEntriesPassingTest:
of NSDictionary. Just pass in a block like so:
for(NSDictionary *myDictionary in myArray){
NSSet *resultSet = [myDictionary keysOfEntriesPassingTest:^(id key, id object, BOOL *stop) {
//assuming that 3500 is an int, otherwise use appropriate condition.
if([[NSNumber numberWithInt:object] isEqual:[NSNumber numberWithInt:3500]]){
return YES;
}else{
return NO;
}
}];
if (resultSet.count>0){
//do whatever to myDictionary
}
}

How do I get all values from a NSDictionaries inside an NSDictionary? [duplicate]

This question already has answers here:
Appending NSDictionary to other NSDictionary
(3 answers)
Closed 9 years ago.
Im working with flickr and in the sample fetch I get this:
{
"api_key" = {
"_content" = 3c6eeeae4711a5f478d3da796750e06b;
};
format = {
"_content" = json;
};
method = {
"_content" = "flickr.test.echo";
};
nojsoncallback = {
"_content" = 1;
};
stat = ok;
}
This is a dictionary with 5 entries (api_key, format, method, nojsoncallback & stat). The first 4 entires are dictionaries themselves.
First off, there is a 5th element in my original dictionary, which is not a dictionary, it is simply the last entry in the original dictionary (the one stat=ok). Furthermore, I want the _content key in every subentry to appear in my individual cells but I dont want to hardcode any values. Do I HAVE to setup an array?
NSDictionary has a nifty little method called valueForKeyPath. Thats your savior here.
[dict valueForKeyPath:#"api_key._content"]
[dict valueForKeyPath:#"format._content"]
[dict valueForKeyPath:#"method._content"]
[dict valueForKeyPath:#"nojsoncallback._content"]
What it does is traverse the key path and fetch the values of content in each JSON substructure. Otherwise you would have had to written a for-loop and loop through it. Neat huh?
Try this
for (NSString *key in dictionary){
id object = dictionary[key];
if ([object isKindOfClass:[NSDictionary class]]) {
//Now you can work on the dictionary object
}
}

Resources