How to create Array of Array in iPhone? - iphone

I want to create a nested array or multidimensional array.
In my data is,
FirstName class year dept lastName
Bob MBA 2000 Comp Smith
Jack MS 2001 Comp McDonald
NSMutableArray *section = [[NSMutableArray alloc] init];
I want to put my data into the section Array.
Eg:
section[0] = [FirstName,LastName];
section[1] = [class, year, dept];
So how can i put the values into array like that.
Please help me out.
Thanks

I would recommend creating a custom data storage class. You could call it PDPerson.h You'll also need the .m file. For each property, do something like this:
In the .h: Declare each of your properties like so:
#interface PDPerson : NSObject{
}
#property(nonatomic, retain) NSString *firstName;
#property(nonatomic, retain) NSString *lastName;
#property(nonatomic, retain) NSString *class;//May want to consider renaming
#property(nonatomic, retain) NSString *year;
#property(nonatomic, retain) NSString *dept;
#end
Then in the .m:
#implementation
#synthesize firstName, lastName;
#synthesize class, year dept;
-(void)dealloc{
[firstName release];
[lastName release];
[class release];
[year release];
[dept release];
}
Each time you want to create a new "Person" in your array, do this:
PDPerson *person = [[PDPerson alloc]init];
You can then easily set the properties of the object like so:
person.firstName = #"John";
person.lastName = #"Smith";
person.class = #"Math";
person.year = #"1995";
person.dept = #"Sciences";
And retrieve them:
firstNameLabel.text = person.firstName;
The nice thing about these objects is that all you have to do now is add the person object to your array:
NSMutableArray *personArray = [[NSMutableArray alloc] init];
[personArray addObject:person];

NSArray *section1 = [NSArray arrayWithObjects: #"1,1", #"1,2", #"1,3", nil];
NSArray *section2 = [NSArray arrayWithObjects: #"2,1", #"2,2", #"2,3", nil];
NSArray *section3 = [NSArray arrayWithObjects: #"3,1", #"3,2", #"3,3", nil];
NSArray *sections = [NSArray arrayWithObjects: section1, section2, section3, nil];
int sectionIndex = 1;
int columnIndex = 0;
id value = [[sections objectAtIndex:sectionIndex] objectAtIndex:columnIndex];
NSLog(#"%#", value); //prints "2,1"
Be warned, this isn't a flexible way of storing data. Consider using CoreData or creating your own classes to represent the data.

You can just nest multiple NSArray instances within an NSArray.
For example:
NSMutableArray* sections = [[NSMutableArray alloc] init];
for (int i = 0; i < numberOfSections; i++)
{
NSMutableArray* personsInSection = [[NSMutableArray alloc] init];
[sections insertObject:personsInSection atIndex:i];
for (int x = 0; x < numberOfPersons; x++)
{
Person* person = [[Person alloc] init];
[personsInSection insertObject:person atIndex:x];
}
}
This may seem like overkill when coming from languages such as C++ or Java, where multidimensional arrays can be created simply by using multiple sequare brackets. But this is way things are done with Objective-C and Cocoa.

Related

How to add NSDictionary of dictionaries to NSArray?

I have a dictionary of dictionaries. This is the structure of my main dictionary:
The content of dictionary(
{
mondaysSales= {
totalSale = "1234.99";
},
tusdaySales= {
totalSale = "1234.99";
},
wednesdaySale={
totalSale = "1234.99";
},
thursdaySale{
totalSale = "1234.99";
},
fridaySale{
totalSale = "1234.99";
}
)
but I want to add each day with the day key to a array. For example:
this would be one of the entries of the array:
fridaySale{
totalSale = "1234.99";
}
Any of you how can accomplish this?, I'll really appreciate your help.
You can loop through the dictionary and add it to the array. Note that dictionaries are not sorted and you probably won't end up with a correct order for your weekdays
NSMutableArray *array = [#[] mutableCopy]
for (NSString* key in dictionary) {
id value = [dictionary objectForKey:key];
[array addObject:value];
}
Why not create a new object type and add that to the array?
StorageObject.h:
#interface StorageObject:NSObject
#property (nonatomic, retain) NSString *day;
#property (nonatomic, retain) NSString *saleType;
#property (nonatomic, retain) NSNumber *saleValue;
#end
StorageObject.m:
#implementation StorageObject
#synthesize
day = _day,
saleType = _saleType,
saleValue = _saleValue;
- (void)dealloc
{
[_day release];
[_saleType release];
[_saleValue release];
[super dealloc];
}
#end
Now just loop through your NSDictionary using:
for(NSString *key in [dictionary1 allKeys])
{
NSDictionary *innerDictionary = [dictionary1 objectForKey:key];
}
For every dictionary returned in that loop, instantiate your custom storage object and add it to the array.
I figure out solution:
NSMutableDictionary *tempDict=[[NSMutableDictionary alloc]init];
[tempDict setObject:[mainDic objectForKey:key] forKey:key];
[myArray addObject:tempDict];
Assuming you have a dictionary of dictionaries:
You can do
NSMutableArray *list = [#[] mutableCopy];
for (NSString *key in [mainDictionary allKeys]) {
NSDictionary *dict = #{
key : [mainDictionary objectForKey:key],
};
[list addObject:dict];
}
There is an easy way to do this just don't create an NSDictionary and instead create an NSArray, by doing the following
NSArray *Array = #[#{#"friday sale, totalSale" : #"1234.99"}]
Or if you want to have specifics gotten from anything else in it.
NSInteger value = 1;
NSArray *Array = #[#{ #"Friday sale, totalSale" : [NSString stringWithFormat:#"%ld", (long)value]}];
Then you get this value from simply saying,
NSString *somestring = Array["Friday sale, totalSale"];

How to sort NSMutableArray of object in ascending or descending order

I have created an NSMutableArray of Object using this code
- (void)viewDidLoad
{
[super viewDidLoad];
NSArray * ary1 = [NSArray arrayWithObjects:#"01/07",#"02/07",#"03/07",#"04/07",#"05/07",#"06/07",#"07/07", nil];
NSArray * ary2 = [NSArray arrayWithObjects:#"First",#"Second",#"Third",#"Forth",#"Fifth",#"Sixth",#"Seventh", nil];
NSArray * ary3 = [NSArray arrayWithObjects:#"1000",#"2000",#"3000",#"4000",#"5000",#"6000",#"7000", nil];
tableAry = [[NSMutableArray alloc] init];
for (int i=0; i<ary1.count; i++) {
//cardSummry will hold the data and give back the model to store in array and we can find that value using model
DataModel *dataModel = [[DataModel alloc] init];
dataModel.date = [ary1 objectAtIndex:i];
dataModel.name = [ary2 objectAtIndex:i];
dataModel.ammount = [ary3 objectAtIndex:i];
[tableAry addObject:dataModel];
}
}
And this is my DataModel Class
.H file
#import <Foundation/Foundation.h>
#interface DataModel : NSObject
//this variable is used to get the data from array
#property (nonatomic,strong) NSString *date;
#property (nonatomic,strong) NSString *name;
#property (nonatomic,strong) NSString *ammount;
//this method will genarate a data model which will be added to array for future use
+ (id)cardSummary:(NSString*)date name:(NSString*)name ammount:(NSString*)ammount;
#end
.M file
#import "DataModel.h"
#implementation DataModel
#synthesize date,name,ammount;
//this method will genarate a data model which will be added to array for future use
+ (id)cardSummary:(NSString*)date name:(NSString*)name ammount:(NSString*)ammount
{
DataModel *dataModel = [[self alloc] init];
[dataModel setDate:date];
[dataModel setAmmount:ammount];
[dataModel setName:name];
return dataModel;
}
#end
Now i want to sort it according to the name in that array i have seen this Question in SO which look like mine and use its answer code to solve my problem but it didn't work for me which is this
[tableAry sortUsingDescriptors:
[NSArray arrayWithObject:[NSSortDescriptor sortDescriptorWithKey:#"name" ascending:YES selector:#selector(caseInsensitiveCompare:)]]];
NSLog(#"tableAry : %#",tableAry);
So how can i sort my array
Update
As #Martin R And #Rick said i have alloc my array but now i got this error.
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[DataModel caseInsensitiveCompare:]: unrecognized selector sent to instance 0x7550850'
You can also use the NSSortDescriptor.
NSSortDescriptor* sortDes = [[NSSortDescriptor alloc] initWithKey:#"your key" ascending:YES];
[_array sortUsingDescriptors:[NSArray arrayWithObject:sortDes]];
Try it.
[tableAry sortUsingComparator:^NSComparisonResult(DataModel *obj1, DataModel *obj2) {
return [obj1.name caseInsensitiveCompare:obj2.name];
}];
-(NSMutableArray*)sortArrayInAssendingOrder:(NSMutableArray*)array{ // array must have numerical value
NSMutableArray *newArray=[NSMutableArray arrayWithArray: array];
NSMutableArray *shortedArray=[[NSMutableArray alloc]init];
for (int i=0; i<=[newArray count]+1; i++) {
NSInteger value_1=[[newArray objectAtIndex:0]integerValue];
for(int j=0; j<[newArray count]; j++){
NSInteger value_2=[[newArray objectAtIndex:j]integerValue];
if(value_1>value_2){
value_1 =nil;
value_1 = value_2;
}
}
[shortedArray addObject:value_1];
[newArray removeObject: value_1];
}
[shortedArray addObject:[newArray objectAtIndex:0]];
return shortedArray;
}
-(NSMutableArray*)shortCardInAssendingOrder:(NSMutableArray*)cardSetArr{
NSMutableArray *shortedArray=[[NSMutableArray alloc]init];
for (int i=0; i<=[cardSetArr count]+1; i++) {
Card *firstCard=[cardSetArr objectAtIndex:0];
for(int j=0; j<[cardSetArr count]; j++){
Card *nextCard=[cardSetArr objectAtIndex:j];
if(firstCard.cardSymbol>nextCard.cardSymbol){
firstCard=nil;
firstCard=nextCard;
}
}
[shortedArray addObject:firstCard];
[cardSetArr removeObject:firstCard];
}
[shortedArray addObject:[cardSetArr objectAtIndex:0]];
return shortedArray;
}
Note: you can use ur tag or any thing else at tha place of cardSymbol

Adding values to two different NSMutableArray without increasing the retain count

I have two simple NSMutableArray that consists of few objects. Some of these objects can be common but need to be stored in both of the arrays as uses of both arrays are defined for totally different purpose.
However, the problem is that after adding same objects to both array, on changing the value of one of the common object, does not reflect in 2nd array.
For example,
Let's say we have two mutable NSArray:
NSMutableArray *mutableArrayOne;
NSMutableArray *mutableArrayTwo;
Now let's create the object definition that these array needs to contain.
#interface: DummyObject : NSObject
{
int objectValue;
}
#property (nonatomic) int objectValue;
-(void) printObjectValue;
#end
Now let's create the base class to store the arrays.
Base Class Definition
#interface: BaseClass : NSObject
{
NSMutableArray *mutableArrayOne;
NSMutableArray *mutableArrayTwo;
}
-(void) init;
-(void) printBothArrays;
#end
Base Class Implementation
#implementation BaseClass
-(void) init
{
// initialize the mutable array.
mutableArrayOne = [[NSMutableArray alloc] initWithCapicity:5];
mutableArrayTwo = [[NSMutableArray alloc] initWithCapicity:5];
DummyObject *dummyObject = [DummyObject alloc];
[dummyObject setObjectValue:5];
DummyObject *dummyObjectTwo = [DummyObject alloc];
[dummyObjectTwo setObjectValue:2];
[mutableArrayOne addObject:dummyObject];
[mutableArrayOne addObject:dummyObjectTwo];
[mutableArrayTwo addObject:dummyObjectTwo];
}
#end
Now let me the modify the DummyObject in array One:
for (DummyObject* dummyObject in mutableArrayOne)
{
[dummyObject setValue:100];
}
Problem
Now here starts the problem when I am printing the values for both array objects:-
Printing First Array
for (DummyObject* dummyObject in mutableArrayOne)
{
[dummyObject printObjectValue];
}
*Output Log (from first array) *
100
100
Printing second Array
for (DummyObject* dummyObject in mutableArrayTwo)
{
[dummyObject printObjectValue];
}
*Output Log (from second array) *
2
So here we can see that MutableArray is keeping the copy of the object, however, I want to store only the reference. That means, on changing the value of the object in 1st array should reflect in 2nd array.
How can we do that?
Do we any other alternative?
Thanks,
Paras Mendiratta
This will ideally work, seems like some issue with setting object.
For e.g. you can check like this -
NSMutableString *firstString = [[NSMutableString alloc] initWithString:#"first"];
NSMutableString *secondString = [[NSMutableString alloc] initWithString:#"second"];
NSMutableArray *originalArray = [[NSMutableArray alloc] initWithObjects: firstString, secondString, nil];
NSMutableArray *copyArray = [[NSMutableArray alloc] initWithObjects: firstString, secondString, nil];
[[copyArray objectAtIndex:0] appendString:#"add some text"];
for (int index = 0; index < [originalArray count]; index++) {
NSLog(#"Original:%# --- copy:%#", [originalArray objectAtIndex:index], [copyArray objectAtIndex:index]);
}
And output is -
2012-05-09 10:28:40.382 Demo[5237:f803] Original:firstadd some text --- copy:firstadd some text
2012-05-09 10:28:40.384 Demo[5237:f803] Original:second --- copy:second
EDIT - (Not adding object at the time of initialization)
NSMutableString *firstString = [[NSMutableString alloc] initWithString:#"first"];
NSMutableString *secondString = [[NSMutableString alloc] initWithString:#"second"];
NSMutableArray *originalArray = [[NSMutableArray alloc] init];
NSMutableArray *copyArray = [[NSMutableArray alloc] init];
[originalArray addObject:firstString];
[copyArray addObject:firstString];
[originalArray addObject:secondString];
[copyArray addObject:secondString];
[[copyArray objectAtIndex:0] appendString:#"add some text"];
for (int index = 0; index < [originalArray count]; index++) {
NSLog(#"Original:%# --- copy:%#", [originalArray objectAtIndex:index], [copyArray objectAtIndex:index]);
}
Output -
2012-05-09 11:11:18.275 Demo[5433:f803] Original:firstadd some text --- copy:firstadd some text
2012-05-09 11:11:18.277 Demo[5433:f803] Original:second --- copy:second

Having problems with Array

SO here's my setup. I have an object called radiostations where I have several strings like callsign, frequency declared and an NSMutableArray called amStationInfo. On my viewcontroller, I access an SQLite database which populates the an array like so...
radiostations.h
#interface radiostations : NSObject {
NSString *format;
NSString *city;
}
#property (nonatomic, retain) NSString *format;
#property (nonatomic, retain) NSString *city;
ViewController.m
radiostations *amStationClass = [[radiostations alloc] init];
NSMutableArray* amStationInfo = [[NSMutableArray alloc] init];
while (sqlite3_step(statement) == SQLITE_ROW)
{
NSString *cityField = [[NSString alloc] initWithUTF8String:
(const char *) sqlite3_column_text(statement, 10)];
NSString *formatField = [[NSString alloc] initWithUTF8String:
(const char *) sqlite3_column_text(statement, 0)];
[amStationInfo addObject:amStationClass];
[amStationClass setCity:cityField];
[amStationClass setFormat:formatField];
}
[tabView reloadData];
sqlite3_finalize(statement);
and then I populate a UITableView
NSString *cityValue = [(radiostations *)[amStationInfo objectAtIndex:indexPath.row] city];
NSString *formatValue = [(radiostations *)[amStationInfo objectAtIndex:indexPath.row] format];
cityLabel.text = cityValue;
formatLabel.text = formatValue;
Initially I was dealing with a few Arrays and this worked just fine. I then changed it so that I was only dealing with one array using a class object and now it's not working. I know the SQLite query and what not works so Im not having any problems with that. It seems as though the array does not get populated.
You are changing the properties of the same radiostations object and adding it over and over again to the array. You need to create a new radiostations object for each row from your sqlite database and add this:
while (...) {
// fetch data as before
radiostations *record = [[radiostations alloc] init];
[record setCity: cityField];
[record setFormat: formatField];
[amStationInfo addObject: record];
[record release];
}
If you are using ARC you need to remove the line [record release];, otherwise it is necessary to avoid leaking those objects.
where did you allocate/init your mutablearray?
something like:
NSMutableArray* amStationInfo = [[NSMutableArray alloc] init];
you need to allocate it once, before to add objects in it

iphone listview with several cells

I have been able to make the listview show a single field of data using parts of the code like below.
NSMutableArray *array;
..
..
array = [[NSMutableArray alloc] init];
[array addObject:#"John Doe"];
However I want to keep several fields, like:
Name
ID
Date of Birth
I assume the NSMutableArrary is a NSString but I need something like a struct in C that holds the fields I need.
The ID would be "Hidden" but I need to access it when the user clicks on the line. How I access the ID and the other fields? How do I set this up so the list has the information?
Does anyone have any example code that might explain how to do this?
EDIT #1: Thanks for the comments, but I am too new to iPhone and really need to find example code on how to do this. While the comments make it sound like can do this, I dont know where to start. Can someone post example code for the idea of 3 fields?
EDIT #2: I have tried everything so far, is the the correct way to do this or should I use the ideas below?
Userrec.m
#import "UserRec.h"
#implementation Userrec
#synthesize Name, ID;
-(id)initWithName:(NSString *)n ID:(NSString *)d {
self.Name = n;
self.ID = d;
return self;
}
#end
UserRec.h
#import <UIKit/UIKit.h>
#interface Userrec : NSObject {
NSString *Name;
NSString *ID;
}
#property (nonatomic, retain) NSString *Name;
#property (nonatomic, retain) NSString *ID;
-(id)initWithName:(NSString *)n ID:(NSString *)d;
#end
UserList.m
#synthesize userrecs;
…
- (void)viewDidLoad {
[super viewDidLoad];
NSString *Name = #"Name";
NSString *ID = #"IID";
Userrec *userrec = [[Userrec alloc] initWithName:Name ID:ID ];
[userrecs addObject:userrec];
NSLog(#"Count %d",[userrecs count]);
[userrec release];
NSLog(#"Count %d",[userrecs count]);
}
After I addobject and check the count its = 0. So I assume something is wrong?
NSMutableDictionary is the best way to go. You can do something as follows:
NSMutableDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:#"John Doe", #"Name", [NSNumber numberWithInt:5], #"ID", nil];
You can keep adding as many fields as you like with that same template, even NSArray objects. I'd look up the documentation if you have any more trouble. Remember, you can only store pointers to objects in an NSDictionary. Things like
NSMutableDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:#"John Doe", #"Name", 5, #"ID", nil];
won't work. Good Luck!
Take a look at an NSMutableDictionary it seems like the exact thing you would want to use
Edit:
Here's some sample code
NSMutableArray *myData = [[NSMutableArray alloc] init];
NSMutableDictionary *myRow = [[NSMutableDictionary alloc] init];
[myRow setObject:#"John Doe" forKey:#"Name"];
[myRow setObject:#"4738" forKey:#"ID"];
[myRow setObject:#"1/23/45" forKey:#"DOB"];
[myData addObject:myRow];
[myRow release];
//Repeat from dictioanry alloc through release for each row you need to add
To display this in a UITableView, you need to have a UITableViewController class. In there override the cellForRowAtIndexPath: function. here is a simple implementation of that function
-(UITableViewCell*) tableView:(UITableView*)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSInteger row = [indexPath row];
static NSString *kCellID = #"cellID";
UITableViewCell *cell = nil;
cell = [tableView dequeueReuseableCellWithIdentifier:kCellID];
if ( cell == nil )
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:kCellID] autorelease];
}
NSMutableDictionary curRow = [myData objectAtIndex:row];
cell.textLabel.text = [curRow objectForKey:#"Name"];
return cell;
}