Want to get key value from NSDictionary - ios

I want to get all key values in an array. Here I used the keyword allKeysForObject. While using allKeysForObject, I got value within parenthesis. I want to store value without parenthesis.
Here is my code:
dict = [[NSMutableDictionary alloc]init];
[dict setValue:#"Hai" forKey:#"1"];
[dict setValue:#"lrd" forKey:#"2"];
NSArray *keys = [dict allKeys];
NSMutableArray *countryArray = [[NSMutableArray alloc]init];
NSMutableArray *keyObjects = [[NSMutableArray alloc]init];
for(NSString* key in keys) {
NSString *obj = [dict objectForKey:key];
[countryArray addObject:obj];
}
for (int i =0; i < [countryArray count]; i++) {
[keyObjects addObject:[dict allKeysForObject: [countryArray objectAtIndex:i]]];
}
NSLog(#"%#",[keyObjects objectAtIndex:0]);
The NSLog value is:
2013-11-28 17:12:48.400 Help[6775:c07] (
1
)
Thanks in advance.

Replace:
NSLog(#"%#",[keyObjects objectAtIndex:0]);
With:
NSLog(#"%#",[keyObjects objectAtIndex:0][0]);
You are storing in keyObjects the value returned by allKeysForObject: which is a NSArray.

You will get all values in an NSDictionary using [dict allValues]. you dont need to manually iterate the array
dict = [[NSMutableDictionary alloc]init];
[dict setValue:#"Hai" forKey:#"1"];
[dict setValue:#"lrd" forKey:#"2"];
NSMutableArray *countryArray = [[dict allValues] mutableCopy];
NSMutableArray *keyObjects = [[NSMutableArray alloc]init];
for (int i =0; i < [countryArray count]; i++) {
[keyObjects addObject:[dict allKeysForObject: [countryArray objectAtIndex:i]]];
}
NSLog(#"%#",[keyObjects objectAtIndex:0][0]);

Instead of using loop for getting all key values from NSDictionary use - (NSArray *)allKeys;
method to do that. It is always good to use given methods than writing our own code to achieve the same.
so replace of the for loop with following code...
keyObjects = [[dict allKeys]mutableCopy]; // mutableCopy because I think you want it mutable as your array is mutable.
EDIT
AFA your code concern, your are getting parenthesis because you are storing all keys in keyObjects array as array, that why you can see those parenthesis out there in you log statement. and this is because allKeysForObject method returns array of keys related to given object.
and if you want it to be done in your way here it is...
for (int i =0; i < [countryArray count]; i++) {
[keyObjects addObject:[dict allKeysForObject: [[countryArray objectAtIndex:i]0]]];
}

While NSLog-ing:
Whenever you see (...) it is array.
Whenever you see {...} it is dictionary.
So in your case it is shown as (1) so this is an array with one object.
Hence you need to do through one level down to retrieve it.
NSLog(#"%#",[[keyObjects objectAtIndex:0] objectAtIndex:0]); //or
NSLog(#"%#",[keyObjects objectAtIndex:0][0]);

Related

Adding NSDictionary to an array

I am not sure what I am missing but i have this for loop below. When I loop through it, the dictionary object gets added to the array like it should each time. But for some reason the next time it loops, it completely replaces all the dictionary object values with the current dictionary value it is looping. So for example I have 5 dictionary objects in my array when it's done looping and all of them have the latest loop values...
NSMutableArray *events = [NSMutableArray array];
NSMutableDictionary *event = [[NSMutableDictionary alloc]init];
NSMutableArray *array = [NSMutableArray arrayWithArray:[[NSUserDefaults standardUserDefaults] objectForKey:#"Update"]];
for (int i = 0; i < [array count]; i = i + 2){
[event setValue:[array objectAtIndex:i+1] forKey:#"Event-Type"];
[event setValue:[array objectAtIndex:i] forKey:#"date"];
[events addObject:event];
}
You would have to allocate a new NSMutableDictionary each iteration of the loop, either at the beginning of each loop (i.e. just move that line into the loop) or when you do addObject you can copy the dictionary using [NSDictionary dictionaryWithDictionary: event];
This is because NSMutableDictionary is an object; It is passed by reference. So you're just putting the same instance of NSMUtableDictionary into your array n times.
You can see this by logging the object at each index of your array at the end, and you can check the memory address to see they're all the same.
Arrays in objective C pass references, not copies. So when you call [events addObject:event] then write to that same event later it gets written over and added newly. Just move the creation of the dictionary inside the for loop and you should be good to go.
You need to alloc init your dictionary inside the loop and also note addition as per Apple Standard always use setObject: forKey: if you are using dictionary. Please refer the below code:-
NSMutableArray *events = [NSMutableArray array];
NSMutableArray *array = [NSMutableArray arrayWithArray:[[NSUserDefaults standardUserDefaults] objectForKey:#"Update"]];
for (int i = 0; i < [array count]; i = i + 2){
NSMutableDictionary *event = [[NSMutableDictionary alloc]init];
[event setObject:[array objectAtIndex:i+1] forKey:#"Event-Type"];
[event setObject:[array objectAtIndex:i] forKey:#"date"];
[events addObject:event];
}

How to remove all dictionaries from NSMutableArray based on the value in the dictionary

I am developing one iPad application.I have one NSMutableArray and NSMutableDictionary .These both are changeable based on the data from the web service.I need to remove some dictionary from my NSMutableArray based on the NSMutableDictionary values. Here I explain the situation through one example:
testArray =[{ language :"ESP"},{language :"ENG"},{language :"ENG"},{language :"FRH"}];
From the test array i need to remove the all Dictionaries which have key value language :"ENG".
I've written code like this:
for(int i =0;i<testArray.count;i++){
NSString *lang = [NSString stringWithFormat:#"%#", [testArray[i] objectForKey:#"language"]];
if([lang isEqualToString:#"ENG"]){
[testArray removeObjectAtIndex:i];
}
}
But it is not working. I think the problem is when I remove the dictionary from at index the array count is also reducing so the loop is executing based on new array count. Some help me to rewrite the code for get exact answer?
This is my favorite way, it's fast, clear and correct.
NSMutableArray *itemsToRemove = [NSMutableArray array];
for (id item in theArray) {
if ([item shouldBeRemoved])// Condition to check the key pair Value
[itemsToRemove addObject:item];
}
[theArray removeObjectsInArray:itemsToRemove];
Try this.
NSMutableArray *arrTemp = [[NSMutableArray alloc]initwithArray:testArray];
for(int i =0;i<testArray.count;i++){
NSString *lang = [NSString stringWithFormat:#"%#", [testArray[i] objectForKey:#"language"]];
if([lang isEqualToString:#"ENG"]){
[arrTemp removeObjectAtIndex:i];
}
}
[testArray removeAllObjects];
testArray = arrTemp;
for(int i =0;i<testArray.count;i++){
NSString *lang = [NSString stringWithFormat:#"%#", [testArray[i] objectForKey:#"language"]];
if([lang isEqualToString:#"ENG"]){
[testArray removeObjectAtIndex:i];
i--;
}
}
Replace your code with below code.
NSMutableArray *arrTemp = [NSMutableArray new];
for(int i =0;i<testArray.count;i++){
NSString *lang = [NSString stringWithFormat:#"%#", [testArray[i] objectForKey:#"language"]];
if([lang isEqualToString:#"ENG"]){
[arrTemp addObject:[NSNumber numberWithInt:i]];
}
}
for(int k=0;k<[arrTemp count];k++)
{
int ii = [[arrTemp objectAtIndex:k]intValue];
[testArray removeObjectAtIndex:ii];
}
let me know it is working or not!!!
Happy Coding!!!
I would implement that using NSPredicate:
NSMutableArray *testArray = [#[#{ #"language" :#"ESP"}, #{#"language" :#"ENG"},
#{#"language" :#"ENG"}, #{#"language" :#"FRH"}] mutableCopy];
NSPredicate *predicate =
[NSPredicate predicateWithFormat:#"language != %#", #"ENG" ];
testArray = [[testArray filteredArrayUsingPredicate:predicate] mutableCopy];
I have just tested it, it works (it is short and nice to read, but NSPredicate can be really slow).
Another way to do it is using enumerateObjectsWithOptions:usingBlock:
[testArray enumerateObjectsWithOptions:NSEnumerationReverse usingBlock:^(NSDictionary *dict, NSUInteger index, BOOL *stop) {
if ([dict[#"language"] isEqualToString:#"ENG"]) {
[testArray removeObjectAtIndex:index];
}
}];
Pleace notice that i use NSEnumerationReverse as NSEnumerationOptions because according to docs of removeObjectAtIndex:- Method :
To fill the gap, all elements beyond index are moved by subtracting 1
from their index.

Adding objects to dictionary in a loop overwrites previous values

I have three NSArrays, and I want to combine them all into a single NSDictionary. The problem is that as I iterate through the arrays and create the dictionary, it overwrites the previous object. In the end I only have one object in my dictionary. What am I doing wrong? Here's my code:
NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
for(int i=0; i<[array0 count]; i++) {
[dict setObject:[array0 objectAtIndex:i]
forKey:#"one"];
[dict setObject:[array1 objectAtIndex:i] f
orKey:#"two"];
[dict setObject:[array2 objectAtIndex:i]
forKey:#"three"];
}
Maybe this will clarify what I mean...
this is the result I'm going for:
{one = array0_obj0, two = array1_obj0, three = array2_obj0},
{one = array0_obj1, two = array1_obj1, three = array2_obj1},
{one = array0_obj2, two = array1_obj2, three = array2_obj2},
etc
Thanks
Issue
You are inserting and replacing the same object at the specific key. So all what dictionary has is its last object at the last index.
Solution
Use this code to add the three arrays into one dictionary with your specific keys.
NSDictionary *yourDictinary = #{#"one": array0, #"two": array1, #"three": array3};
Edit
If you need to add objects of your NSMutableArrays to one NSDictionary you can follow the answer posted by #ElJay, but that's not a good practice, since you are dealing with multiple objects with unique keys.
Update
To do that thing, we are talking about a single NSMutableArray and multiple NSDictinarys.
Follow this code:
NSMutableArray *allObjects = [NSMutableArray new];
for(int i=0; i<[array0 count]; i++) {
dict = #{#"one": array0[i], #"two": array1[i], #"three": array2[i]};
[allObjects addObject:dict];
}
Here ya go:
NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
for(int i=0; i<[array0 count]; i++) {
[dict setObject:[array0 objectAtIndex:i] forKey:[NSString stringWithFormat:#"arr0_%d", i]];
[dict setObject:[array1 objectAtIndex:i] forKey:[NSString stringWithFormat:#"arr1_%d", i]];
[dict setObject:[array2 objectAtIndex:i] forKey:[NSString stringWithFormat:#"arr2_%d", i]];
}
Edit - with revised question:
self.array0 = #[#"Array0_0",#"Array0_1",#"Array0_2", #"Array0_3"];
self.array1 = #[#"Array1_0",#"Array1_1",#"Array1_2", #"Array1_3"];
self.array2 = #[#"Array2_0",#"Array2_1",#"Array2_2", #"Array2_3"];
NSMutableArray *finalArray = [[NSMutableArray alloc] init];
for (int i=0; i< [_array0 count]; i++) {
NSDictionary *dict = #{#"one":[_array0 objectAtIndex:i], #"two":[_array1 objectAtIndex:i],#"three":[_array2 objectAtIndex:i]};
[finalArray addObject:dict];
}
NSLog(#"finalArray = %#", [finalArray description]);
You're reusing the keys ("one", "two" and "three") through each iteration of the loop. Keys in an NSDictionary have to be unique.
If you want many dictionary but only three keys, you should save each dict in an array.

NSMutableArray with NSDictionary to NSMutableDictionary

Here is the situation:
I have a request on AFNetworking that retrieves me a JSON with an NSArray.
My goal is to mutate the NSDictionaries inside it. I already made a mutableCopy of the array, but I want to know if I can easily mutate all the content. Will I have to iterate through the array manually?
NSJSONSerialization has options to allow you to control the mutability of the resulting data structure. Just pass the appropriate ones (probably NSJSONReadingMutableContainers) and there you go.
You cannot mutate NSDictionary, just because only NSMutableDictionary has method setObject:forKey:
So you should create mutableCopy of each dictionary and empty mutable array. Then with a forloop fill that array. Your code should be so:
- (NSMutableArray *)mutatedArrayFromArray:(NSArray *)array
{
NSMutableArray *resultArray = [NSMutableArray new];
if([array count] > 0)
{
for(int i = 0; i < count; i++)
{
NSMutableDictionary *mutatedItem = [[array objectAtIndex:i] mutableCopy];
[resultArray addObject:mutatedItem];
[mutatedItem release]; // only with ARC disabled
}
}
return [result autorelease]; // if ARC enabled : return result;
}

NSMutableDictionary -- using allKeysforObject not retrieving array values

NSMutableDictionary *expense_ArrContents = [[NSMutableDictionary alloc]init];
for (int i = 1; i<=4; i++) {
NSMutableArray *current_row = [NSMutableArray arrayWithObjects:#"payer_id",#"Expense_Type_id",#"Category_Id",#"SubCategory_Id",nil];
[expense_ArrContents setObject:current_row forKey: [NSNumber numberWithInt:i]];
}
NSArray *newArray = [expense_ArrContents allKeysForObject:#"payer_id"];
NSLog(#"%#",[newArray description]);
i want to get the list of key values containing the particular object which is in the array of values stored in nsmutabledictionary for a particular key.
In the line where you get all the keys ([expense_ArrContents allKeysForObject:#"payer_id"];) you actually get keys for an object that is not in any of the array's items. This #"player_id" is different object than the #"player_id" you added in current_row. In fact, maybe all of your rows have different #"player_id" objects (except if the compiler has made some optimization - maybe it threats that same string literal as one object instead of creating new object for each iteration).
Try creating an NSString object for the #"player_id" which you add to the current_row and then get all the keys for that same object:
NSString* playerId = #"player_id";
for(){
NSMutableArray *current_row = [NSMutableArray arrayWithObjects: playerId,...];
...
}
NSArray *newArray = [expense_ArrContents allKeysForObject:playerId];
Your NSArray *newArray = [expense_ArrContents allKeysForObject:#"payer_id"]; will not return any value because in expense_ArrContents there is no such key(#"payer_id"), instead there are keys like 1,2,3 etc.What is your requirement?Want to see what all keys are there in expense_ArrContents just log
NSArray*keys=[expense_ArrContents allKeys];
Try this :
NSMutableArray *array_key=[[NSMutableArray alloc]init];
for (NSString *key in expense_ArrContents) {
if ([[expense_ArrContents objectForKey:key] containsObject:#"payer_id"]) {
[array_key addObject:key];
}
}

Resources