tags:

views:

4118

answers:

5

Hi, how can I modify a 2d array in objective c? I need to create a mutable one.

For example I have:

NSMutableArray *sections;
NSMutableArray *rows;

Each item in sections consists of array rows. Rows is an array that contains objects.

And I want to do something like this:

[ sections[i] addObject: objectToAdd]; //I want to add a new row

In order have something like this: section 0, rows: obj1, obj2, obj3 section 1, rows: obj4, obj5, obj6, obj 7...

Is there a way to implement it in objective-c?

+11  A: 

First, you must allocate and initialize your objects before use, something like: NSMutableArray * sections = [[NSMutableArray alloc] initWithCapacity:10]; For the rows, you need one object for each, not a single NSMutableArray * rows;

Second, you cannot access an array element with section[i] You have to use [sections objectAtIndex:i] for reading and [section replaceObjectAtIndex:i withObject: objectToAdd] for writing.

Third, an array cannot have holes, i.e., obj1, nil, obj2. You must provide actual object to every index. If you do need to put nothing, you can use NSNull object.

Moreover, don't forget that you can also store Objective-C objects in plain C arrays:

id table[lnum][rnum];
table[i][j] = myObj;
mouviciel
+1 for `id` type in straight C arrays.
Tim
Excellent suggest to use plain C arrays, especially where array dimensions are known ahead of time.
timbo
+4  A: 

If you want to do this using arrays, you can intialize your sections array, then add a rows array as follows:

NSMutableArray *sections = [[NSMutableArray alloc] init];
NSMutableArray *rows = [[NSMutableArray alloc] init];
//Add row objects here

//Add your rows array to the sections array
[sections addObject:rows];

If you want to add this rows object at a certain index, use the following:

//Insert your rows array at index i
[sections insertObject:rows atIndex:i];

You can then modify this rows array by retrieving the array:

//Retrieve pointer to rows array at index i
NSMutableArray *rows = [sections objectAtIndex:i]
//modify rows array here

You could always create your own class called Section, which has an NSMutableArray member called rows; then you store your rows inside this array, and store the Section objects in an array:

@interface Section : NSObject {
    NSMutableArray *rows;
}

Then you simply create Section items, and you can create methods inside your class to add/remove row items. Then you package all the Sections items up inside another array:

Section *aSection = [[Section alloc] init];
//add any rows to your Section instance here

NSMutableArray *sections = [[NSMutableArray alloc] init];
[sections addObject:aSection];

This becomes more useful if you want to add more properties for each Section instance.

Perspx
+3  A: 

The language has no support for multi-dimensional object-oriented arrays, but you can make a class that does it using an NSMutableArray full of NSMutableArrays, like the following. I haven't tried compiling this or anything, I just typed it in.

@interface SectionArray : NSObject {
  NSMutableArray *sections;
}
- initWithSections:(NSUInteger)s rows:(NSUInteger)r;
+ sectionArrayWithSections:(NSUInteger)s rows:(NSUInteger)r;
- objectInSection:(NSUInteger)s row:(NSUInteger)r;
- (void)setObject:o inSection:(NSUInteger)s row:(NSUInteger)r;
@end
@implementation SectionArray
- initWithSections:(NSUInteger)s rows:(NSUInteger)r {
  if ((self = [self init])) {
    sections = [[NSMutableArray alloc] initWithCapacity:s];
    NSUInteger i;
    for (i=0; i<s; i++) {
      NSMutableArray *a = [NSMutableArray arrayWithCapacity:r];
      for (j=0; j<r; j++) {
        [a setObject:[NSNull null] atIndex:j];
      }
      [sections addObject:a];
    }
  }
  return self;
}
+ sectionArrayWithSections:(NSUInteger)s rows:(NSUInteger)r {
  return [[[self alloc] initWithSections:s rows:r] autorelease];
}
- objectInSection:(NSUInteger)s row:(NSUInteger)r {
  return [[sections objectAtIndex:s] objectAtIndex:r];
}
- (void)setObject:o inSection:(NSUInteger)s row:(NSUInteger)r {
  [[sections objectAtIndex:s] replaceObjectAtIndex:r withObject:0];
}
@end

You'd use it like this:

SectionArray *a = [SectionArray arrayWithSections:10 rows:5];
[a setObject:@"something" inSection:4 row:3];
id sameOldSomething = [s objectInSection:4 row:3];
Jack Nutting
A: 

I must say my dear friend Jack.. complete fine example...

Worked wonderfully mate...

Thanks a ton...

y ramesh rao
A: 

FYI: Jack's code needs a bunch of work before it works. Among other issues, the autorelease can cause the data to get released before you access it and his usage calls the class method arrayWithSections:rows: when it is actually defined as sectionArrayWithSections:rows:

I may try to post actual working code later if I get a chance.