Adding NSDictionary to an array - ios

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];
}

Related

how to do shift and push operation in objective c

I have an array [1,2,3,4]
I need to continously shift and push one element into the same array
so that the first variable values will be 1,2,3,4,1,2,3,4,...
and second variable values will be 2,3,4,1,2,3,4,1,...
How to do that??
Use NSMutableArray like:
1) to get the object at the first position:
object = [nameArray firstObject];
[nameArray removeObjectAtIndex:0];
2) then insert it in last position:
[nameArray addObject:object];
p.s. remember to always add some sanity checks.
You would need
- exchangeObjectAtIndex:withObjectAtIndex:
Exchanges the objects in the array at given indices.
See Documentation here
Example
NSMutableArray *array = [NSMutableArray array];
[array setArray:#[#"Eezy",#"Tutorials",#"Website"]];
[array exchangeObjectAtIndex:0 withObjectAtIndex:2];
NSLog(#"%#",array);
NSMutableArray *obj = [NSMutableArray arrayWithObjects:#"1",#"2",#"3",nil];
[obj exchangeObjectAtIndex:0 withObjectAtIndex:obj.count - 1];
NSLog(#"%#",obj);

How to dynamically create a number of NSMutableArray(s)?

On touch up inside of SAVE button, the following code is executed:
- (IBAction)onSave:(id)sender {
savecount++;
[self saveNumberOfContacts];
NSMutableArray *myArray = [[NSMutableArray alloc] init];
[myArray addObject:nameTextField.text];
[myArray addObject:phoneTextField.text];
[myArray addObject:addressTextField.text];
[myArray addObject:cityTextField.text];
[myArray addObject:stateTextField.text];
[myArray addObject:zipcodeTextField.text];
[myArray writeToFile:[self saveFilePath] atomically:YES];
}
This creates a single array. I want to know how to dynamically create multiple arrays with the savecount variable suffixed at end of the array name.
For example, if my savecount is 3, then myArray1, myArray2, myArray3 should be created.
P.S. savecount changes its value dynamically.
EDIT: i dont want this method creating a number of arrays every time i call it. See, the user's info is stored in myArray1 when i click save for the first time. Now, the savecount gets increemented(say,savecount=2). When i enter another user's details and click save, i dont want myArray1 to be overwritten or disturbed; the second user's details must be independently saved in myArray2.
NSMutableArray *holder;
- (void)viewDidLoad
{
holder = [[NSMutableArray alloc] init];
}
- (IBAction)onSave:(id)sender {
savecount++;
[self saveNumberOfContacts];
NSMutableArray *myArray = [[NSMutableArray alloc] init];
[myArray addObject:nameTextField.text];
[myArray addObject:phoneTextField.text];
[myArray addObject:addressTextField.text];
[myArray addObject:cityTextField.text];
[myArray addObject:stateTextField.text];
[myArray addObject:zipcodeTextField.text];
[myArray writeToFile:[self saveFilePath] atomically:YES];
[holder addObject:myArray];
}
Have one global array in which you can hold dynamically created array. Now when you get value from holder, you will have separated myArray object.
If you are only using these arrays within one method, you could instead store the arrays in an array. This doesn't give you array names such as myArray1, myArray2, etc, but accomplishes the same overall task. Here's an example:
NSMutableArray *myArrays = [[NSMutableArray alloc] initWithCapacity:savecount];
for (NSUInteger i = 0; i < savecount; i++) {
NSMutableArray *newArray = [[NSMutableArray alloc] init];
[myArrays addObject:newArray];
[newArray addObject:nameTextField.text];
// continue adding your objects to newArray
}
Now you can reference your arrays as [myArrays objectAtIndex:0]...[myArrays objectAtIndex:savecount-1].
I think your problem is the path of save, or same path with appended array data.
If save data to different path:
- (NSString*)saveFilePath{
return [NSString stringWithFormat:#"%#/%#%d.%#", thePathToSave, fileName, savecount, fileType];
}
If save to same path with appended array data:
Replace:
[myArray writeToFile:[self saveFilePath] atomically:YES];
with
NSArray *fileData = [NSArray arrayWithContentsOfFile:[self saveFilePath]];
NSMutableArray *preDatas = nil;
if (preDatas.count == 0) {
preDatas = [NSMutableArray array];
}
else{
preDatas = [NSMutableArray arrayWithArray:fileData];
}
[preDatas addObject:myArray];
[preDatas writeToFile:[self saveFilePath] atomically:YES];

Want to get key value from NSDictionary

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]);

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