Reputation: 2048
I am trying to create a class where the width and height of a 2 dimensional array can be dynamically created at the point of initialisation with init parameters.
I have been looking through the web for hours and cannot find a way.
Using a standard C syntax [][]
does not allow for a variable to be used to declare the array.
The mutable arrays within Objective C, in all examples I have seen, require the objects to be hard coded at the time of creation.
Is there a way of creating a 2 dimensional array within an object with parameters to define the sizes at the point of creation?
Hoping someone can tell me what I am missing...
Upvotes: 4
Views: 9010
Reputation: 318
Here is another pure Objective C Version
#import foundation.h
@interface ZTwoDimensionalArray : NSObject{
@package
NSMutableArray* _array;
int _rows, _columns;
}
-(id) initWIthRows:(int)numberOfRows andColumns:(int) numberOfColumns;
-(id) getObjectAtRow:(int) row andColumn:(int)column;
-(void) setObject:(id) anObject atRow:(int) row andColumn:(int)column;
@end
#import "ZTwoDimensionalArray.h"
@implementation ZTwoDimensionalArray
-(id) initWIthRows:(int)numberOfRows andColumns:(int) numberOfColumns{
if (self = [super init]) {
_array = [NSMutableArray initWithCapacity:numberOfRows*numberOfColumns];
_rows = numberOfRows;
_columns = numberOfColumns;
}
return self;
}
-(id) getObjectAtRow:(int) row andColumn:(int)column{
return [_array objectAtIndex: row*_rows + column];
}
-(void) setObject:(id) anObject atRow:(int) row andColumn:(int)column{
[_array insertObject:anObject atIndex:row*_rows + column];
}
-(void) dealloc{
[_array release];
}
@end
Upvotes: 3
Reputation: 163238
You can do this quite easily by writing a category on NSMutableArray
:
@interface NSMutableArray (MultidimensionalAdditions)
+ (NSMutableArray *) arrayOfWidth:(NSInteger) width andHeight:(NSInteger) height;
- (id) initWithWidth:(NSInteger) width andHeight:(NSInteger) height;
@end
@implementation NSMutableArray (MultidimensionalAdditions)
+ (NSMutableArray *) arrayOfWidth:(NSInteger) width andHeight:(NSInteger) height {
return [[[self alloc] initWithWidth:width andHeight:height] autorelease];
}
- (id) initWithWidth:(NSInteger) width andHeight:(NSInteger) height {
if((self = [self initWithCapacity:height])) {
for(int i = 0; i < height; i++) {
NSMutableArray *inner = [[NSMutableArray alloc] initWithCapacity:width];
for(int j = 0; j < width; j++)
[inner addObject:[NSNull null]];
[self addObject:inner];
[inner release];
}
}
return self;
}
@end
Usage:
NSMutableArray *dynamic_md_array = [NSMutableArray arrayOfWidth:2 andHeight:2];
Or:
NSMutableArray *dynamic_md_array = [[NSMutableArray alloc] initWithWidth:2 andHeight:2];
Upvotes: 6
Reputation: 4397
Here's another way. Of course this is just for int but the code could easily be altered for other datatypes.
AOMatrix.h:
#import <Cocoa/Cocoa.h>
@interface AOMatrix : NSObject {
@private
int* matrix_;
uint columnCount_;
uint rowCount_;
}
- (id)initWithRows:(uint)rowCount Columns:(uint)columnCount;
- (uint)rowCount;
- (uint)columnCount;
- (int)valueAtRow:(uint)rowIndex Column:(uint)columnIndex;
- (void)setValue:(int)value atRow:(uint)rowIndex Column:(uint)columnIndex;
@end
AOMatrix.m
#import "AOMatrix.h"
#define INITIAL_MATRIX_VALUE 0
#define DEFAULT_ROW_COUNT 4
#define DEFAULT_COLUMN_COUNT 4
/****************************************************************************
* BIG NOTE:
* Access values in the matrix_ by matrix_[rowIndex*columnCount+columnIndex]
****************************************************************************/
@implementation AOMatrix
- (id)init {
return [self initWithRows:DEFAULT_ROW_COUNT Columns:DEFAULT_COLUMN_COUNT];
}
- (id)initWithRows:(uint)initRowCount Columns:(uint)initColumnCount {
self = [super init];
if(self) {
rowCount_ = initRowCount;
columnCount_ = initColumnCount;
matrix_ = malloc(sizeof(int)*rowCount_*columnCount_);
uint i;
for(i = 0; i < rowCount_*columnCount_; ++i) {
matrix_[i] = INITIAL_MATRIX_VALUE;
}
// NSLog(@"matrix_ is %ux%u", rowCount_, columnCount_);
// NSLog(@"matrix_[0] is at %p", &(matrix_[0]));
// NSLog(@"matrix_[%u] is at %p", i-1, &(matrix_[i-1]));
}
return self;
}
- (void)dealloc {
free(matrix_);
[super dealloc];
}
- (uint)rowCount {
return rowCount_;
}
- (uint)columnCount {
return columnCount_;
}
- (int)valueAtRow:(uint)rowIndex Column:(uint)columnIndex {
// NSLog(@"matrix_[%u](%u,%u) is at %p with value %d", rowIndex*columnCount_+columnIndex, rowIndex, columnIndex, &(matrix_[rowIndex*columnCount_+columnIndex]), matrix_[rowIndex*columnCount+columnIndex]);
return matrix_[rowIndex*columnCount_+columnIndex];
}
- (void)setValue:(int)value atRow:(uint)rowIndex Column:(uint)columnIndex {
matrix_[rowIndex*columnCount_+columnIndex] = value;
}
@end
Upvotes: 1