Getting NSmutableDictionary key from two mutable arrays - ios

I have three mutable arrays
#interface PickeriviewAndTableViewController ()
//Create mutableArray for tableView
#property(strong,nonatomic)NSMutableArray *msgYear;
#property(strong,nonatomic)NSMutableArray *msgSeason;
#property(strong,nonatomic)NSMutableArray *msgCourse;
I want to add element to array msgCourse[ ] using the key generating from the first two arrays msgYear[ ] and msgSeason[ ].
Then I want to populate the msgCourse[] array using a button
- (IBAction)addCourse:(UIButton *)sender {
//To get value from pickerView, prepare for key and contents
NSInteger numRow=[picker selectedRowInComponent:kNumComponent];//0=1st,1=2nd,etc
NSInteger SeaRow=[picker selectedRowInComponent:kSeaComponent];//0=fall,1=spring,2=summer
NSInteger CourseRow=[picker selectedRowInComponent:kCourseComponent];
NSString *num=Number[numRow];
NSString *season=Season[SeaRow];
NSString *course=Course[CourseRow];
NSString *CourseToAdd=[[NSString alloc ]initWithFormat:#"%# ",course];
NSString *SeasonToAdd=[[NSString alloc ]initWithFormat:#"%# ",season];
NSString *YearToAdd=[[NSString alloc ]initWithFormat:#"%# ",num];
// Try to generate key from YearToAdd and SeasonToAdd and fill in content
NSMutableArray *keys = [[NSMutableArray alloc] init];
NSMutableDictionary *contents = [[NSMutableDictionary alloc] init];
NSString *keyFromYearAndSeason = #"Don't_know_what_to_do_here";
[contents setObject:[NSArray arrayWithObjects:#"Don't_know_how", nil] forKey:keyFromYearAndSeason];
[keys addObject:keyFromYearAndSeason];
[self setSectionKeys:keys];
[self setSectionContents:contents];
}
My question is: How to complete my code by replacing these "Don't know how" lines of code here please?
Update: To be more clear, key is generating from msgYear[ ] and msgSeason[ ] e.g. '2001 fall', dictionary is filled with course e.g. 'chemistry','math'.

The link to your other question helped provide context for what you are trying to achieve.
You don't need to create a dictionary or an array inside the addButtton method - you should have your dictionary as a property that is already initialised.
Then, in add button you retrieve the array associated with the key - if the value is nil then you create a new array and put the course in. If the value isn't nil simply add the course to the array.
#property (strong,nonatomic) NSMutableDictionary *tableEntries; // alloc/init this in viewDidLoad
- (IBAction)addCourse:(UIButton *)sender {
//To get value from pickerView, prepare for key and contents
NSInteger numRow=[picker selectedRowInComponent:kNumComponent];//0=1st,1=2nd,etc
NSInteger SeaRow=[picker selectedRowInComponent:kSeaComponent];//0=fall,1=spring,2=summer
NSInteger CourseRow=[picker selectedRowInComponent:kCourseComponent];
NSString *num=Number[numRow];
NSString *season=Season[SeaRow];
NSString *course=Course[CourseRow];
NSString *key=[NSString stringWithFormat:#"%# %#",num,season];
NSMutableArray *courses=self.tableEntries[key];
if (courses == nil) {
courses=[NSMutableArray new];
self.tableEntries[key]=courses;
}
[courses addObject:course];
}
NSDictionarys are unordered, so you need to give some thought to how you want to order the data in your table. You could use an array to hold the keys as in your original code and then sort this array.

Related

Obj C - Accessing custom class properties from and array of class objects

I have a custom object class with some properties lets say.
#property (nonatomic,retain) NSString *Name;
#property (nonatomic,retain) NSString *ImgURL;
#property (nonatomic,retain) NSArray *Messages;
I then go through a loop and populate the data and add each instance to an array like this
for(NSDictionary *eachEntry in details)
{
ClientData *client;
client.Name = [eachEntry objectForKey:#"name" ];
client.ImgURL = [eachEntry objectForKey:#"img"];
client.Messages = [eachEntry objectForKey:#"message" ];
[_Data addObject:client];
}
now in a table i want to display some of this data in a list, how can i get access to each property by name not key or index.
so at the moment i have this in my cellForRowAtIndexPath
NSString *name = [[self.Data objectAtIndex:indexPath.row] objectForKey:#"name"];
obviously this doesn't work because i haven't set keys
and i don't want to do this
NSString *name = [[self.Data objectAtIndex:indexPath.row] objectAtIndex:1];
How can i access Client.Name etc
self.Data is an array of ClientData objects so you can just do:
NSString *Name = ((ClientData *)[self.Data objectAtIndex:indexPath.row]).Name;
or:
ClientData *clientData = self.Data[indexPath.row];
NSString *name = clientData.Name;
Key Value Coding (KVC). Replace objectForKey with valueForKey.

Populating NSmutableDictionary error

Greeting. I have a NSmutableDictionary and want to populate it.
- (IBAction)addCourse:(UIButton *)sender {
//NSMutableArray *keys = [[NSMutableArray alloc] init];
NSMutableDictionary *contents = [[NSMutableDictionary alloc] init];
//To add content and keys
NSInteger numRow=[picker selectedRowInComponent:kNumComponent];//0=1st,1=2nd,etc
NSInteger SeaRow=[picker selectedRowInComponent:kSeaComponent];//0=fall,1=spring,2=summer
NSInteger CourseRow=[picker selectedRowInComponent:kCourseComponent];
NSString *num=Number[numRow];
NSString *season=Season[SeaRow];
NSString *course=Course[CourseRow];
NSString *AddKey=[NSString stringWithFormat:#"%# %#",num,season];
[contents setObject:[NSMutableArray arrayWithObjects:course, nil] forKey:AddKey];
// NSLog(#"%#", key);//test key here, it works
NSLog(#"Dictionary: %#", [contents description]);//test dictionary here
...}
Here, I have a button, when I push it, num and season and form a key, and the related course will be add to the dictionary. However, when I test it with
NSLog(#"Dictionary: %#", [contents description]);
to show all the content in the dictionary, Only the last record in my selection is shown. In other words, when populating the dictionary, the previous data were override by the later one. What is the problem please?
Update: Thanks for Javier's advice. It fix this problem. But now in the new situation, only one key can hold one content. The following content will override the old one, why is that please?
NSMutableDictionary *contents is not retained by any object of your controller and when the method finishes, that object will be released automatically .
Try declaring contents as a property:
#property (nonatomic,strong) NSMutableDictionary *contents;

populating NSMutableArray not working

Hi I have an instance variable NSMutable Array.
I declare it as such
#property (nonatomic, assign) NSMutableArray *list;
In viewDidLoad I instantiate it.
self.list = [NSMutableArray array];
I then make a string consisting of the text of text fields and add it to the array.
NSString * lines = [NSString stringWithFormat:#"%#,%#,%#,%#,%#", [self.crabText text], [self.trawlText text], [self.trapText text], [self.vesselText text], [self.lengthText text]];
[self.list addObject:lines];
This is apart of a function which will keep on adding new values of the text fields into the array.
I display the contents of the array with
int i;
int count;
for (i = 0, count = [self.list count]; i < count; i = i + 1)
{
NSString *element = [self.list objectAtIndex:i];
NSLog(#"The element at index %d in the array is: %#", i, element); // just replace the %# by %d
}
However, the app crashes when I try to print the contents of the array and I get
EXC_BAD_ACCESS_CODE
Any ideas?
Thanks!
Replace your declaration like this :
#property (nonatomic, strong) NSMutableArray *list; // strong and not assign
Initialize your array in your viewDidLoad :
self.list = [NSMutableArray array];
and add one by one your string :
[self.list addObject:self.crabText.text];
[self.list addObject:self.trawlText.text];
....
Next, modify your for loop :
for (int i = 0, i < self.list.count, i++)
{
NSLog(#"The element at index %d in the array is: %#", i, [self.list objectAtIndex:i]);
}
Another way to do this would be to declare the array this way in your header file
#interface yourViewController : UIViewController
{
NSMutableArray* list;
}
#end
Then in the ViewDidLoad
list = [[NSMutableArray alloc] init];
Everything else can be done just as Jordan said. Though I'm not sure if there is a difference in performance between either implementation.

NSMutableArray with multiple properties [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
I have a rather large NSMutableArray with class files. The array has multiple properties like so:
[Element elementsName:#"Lithium" elementsNumber:#"3"],
[Element elementsName:#"Beryllium" elementsNumber:#"4"],
[Element elementsName:#"Boron" elementsNumber:#"5"],
[Element elementsName:#"Carbon" elementsNumber:#"6"],
[Element elementsName:#"Nitrogen" elementsNumber:#"7"],
[Element elementsName:#"Oxygen" elementsNumber:#"8"],
[Element elementsName:#"Fluorine" elementsNumber:#"9"],
[Element elementsName:#"Neon" elementsNumber:#"10"],
I need to be able to access the elementsName and the elementsNumber separately.
Would anybody know how to do this, and is it possible? Thanks! (More code below!)
Element.h (class for the array)
#interface Element : NSObject
{
NSString *name;
NSString *number;
}
#property(nonatomic, copy)NSString *name;
#property(nonatomic, copy)NSString *number;
+(id)elementsName:(NSString *)name elementsNumber:(NSString *)number;
and Element.m
#import "Element.h"
#implementation Element;
#synthesize number;
#synthesize name;
+(id)elementsName:(NSString *)name elementsNumber:(NSString *)number
{
Element *newElement = [[self alloc] init];
newElement.name = name;
newElement.number = number;
return newElement;
}
#end
You could try something like this:
for(int i = 0; i<elementArray.count; i++)
{
NSString *name = ((Element*)[elementArray objectAtIndex:i]).name;
NSString *number = ((Element*)[elementArray objectAtIndex:i]).number;
}
Is this what you are looking for? :
// returns an array of all numbers
NSArray *numbers = [elementArray valueForKey:#"number"];
// returns an array of all names
NSArray *names = [elementArray valueForKey:#"name"];
This is called KVC (Key-Value Coding) and uses strings to access an object's property. This example goes through all of the elements in the array and asks for its number or name property, then returns the result as an array.
This could also be achieved with a for-loop. I am mainly including this to give you an idea of what is happening:
NSMutableArray *names = [NSMutableArray array];
NSMutableArray *numbers = [NSMutableArray array];
for (Element *e in elementsArray) {
[names addObject:e.name];
[numbers addObject:e.number];
}
Obviously this would work as well, but why not use valueForKey: when it is designed for this?
You can use NSDictionary instead.
NSArray *arrOfDic=#[#{#"elementsName":#"Lithium",#"elementsNumber":#"3"},
#{#"elementsName":#"Beryllium",#"elementsNumber":#"4"},
#{#"elementsName":#"Boron",#"elementsNumber":#"5"},
#{#"elementsName":#"Carbon",#"elementsNumber":#"6"},
#{#"elementsName":#"Nitrogen",#"elementsNumber":#"7"}];
NSLog(#"dic is %#",arrOfDic);
Get your elements and their number as
NSLog(#"FirstObject is Element = %# Element No = %#",arrOfDic[0][#"elementsName"],arrOfDic[0][#"elementsNumber"]);
NSLog(#"SecondObject is Element = %# Element No = %#",arrOfDic[1][#"elementsName"],arrOfDic[1][#"elementsNumber"]);
And whats wrong with your file it is working fine.
NSMutableArray *mArray=[[NSMutableArray alloc] init];
[mArray addObject:[Element elementsName:#"Lithium" elementsNumber:#"3"]];
[mArray addObject:[Element elementsName:#"Beryllium" elementsNumber:#"5"]];
[mArray addObject:[Element elementsName:#"Boron" elementsNumber:#"6"]];
Element *element=(Element*)[mArray objectAtIndex:0];
NSLog(#"My first element is name = %# ,number = %#",element.name,element.number);
output---
My first element is name = Lithium ,number = 3

How to save CustomCell data in an Array?

i have a customcell in my UITableView. This custom cell has a label and text box. when the user fills in the data (4-5 fields) and clicks the Save button. I want to save the Data he inputs.
How can i do that??
I just have around 5-6 fields max. It would be great if you could give some examples on how i can get this done.
One way: Save your data in a dictionary.
Are you trying to pass the data back to the tableview? If so, you will have to save the info in a data structure and then pass it using a defined protocol.
Edit according to your comments:
In a case like this, Apple recommends to use the Delegate-Pattern. Basically, what you do is this:
#protocol FirstDataVCDelegate;
#interface FirstDataVC : UIViewController
#property (weak, nonatomic) id<FirstDataVCDelegate> delegate;
//...
#end
#protocol FirstDataVCDelegate <NSObject>
- (void)firstDataVC:(FirstDataVC *)dataVC didCollectData:(NSDictionary *)data;
#end
#interface RootVC: UIViewController<FirstDataVCDelegate>
//...
#end
#implementation RootVC
- (void)firstDataVC:(FirstDataVC *)dataVC didCollectData:(NSDictionary *)data
{
NSString *name = [data valueForKey:#"name"];
[self.completeData setValue:name forKey:#"name"];
}
#end
In this case RootVC would be the VC who wants to send the whole data. FirstDataVC is one of the VCs where the user inputs data.
Every VC that get userinput has to provide a protocol, that the RootVC implements.
Here is some more about delegation.
You can make a data Structure of the data that he will fill, after save button is clicked. set these values to the data structure
Also you can use NSMutableDictionary key-value storage
Example: let say we have 4 UITextFeilds textFeild1, textFeild2, textFeild3, textFeild14
NSMutableDictionary *dic = [NSMutableDictionary dictionary];
[dic addObject: textFeild1.text forValue: #"val1"];
[dic addObject: textFeild2.text forValue: #"val2"];
[dic addObject: textFeild3.text forValue: #"val3"];
[dic addObject: textFeild4.text forValue: #"val4"];
//Now you have the values and can retrieve them by:
NSString *value1 = [dic valueForKey:#"val1"];
Try with below code:
- (UITableViewCell *)tableView: (UITableView *)tableView cellForRowAtIndexPath: (NSIndexPath *)indexPath
{
UITableViewCell *cell = [self.tabTeamDetails dequeueReusableCellWithIdentifier:#"customcellIdentifier"];
get UItextfeild and assign tag as below
textbox.tag = indexpath.row; //used to refer particular textfiled
}
In save button action:
NSMutableDictionary *dic = [[NSMutableDictionary alloc] init];
//for(i=0;i<noofrowsintableview;i++){
NSString *text = (NSString *)[self.view viewWithTag:i];
[dic addObject:[NSString stringWithFormat:text] forValue: i];
}

Resources