Creating a two dimensional array in Objective-C - objective-c

Whats the easiest way to declare a two dimensional array in Objective-C? I am reading an matrix of numbers from a text file from a website and want to take the data and place it into a 3x3 matrix.
Once I read the URL into a string, I create an NSArray and use the componentsSeparatedByString method to strip of the carriage return line feed and create each individual row. I then get the count of the number of lines in the new array to get the individual values at each row. This will give mw an array with a string of characters, not a row of three individual values. I just need to be able to take these values and create a two dimensional array.

If it doesn't need to be an object you can use:
float matrix[3][3];
to define a 3x3 array of floats.

You can use the Objective C style array.
NSMutableArray *dataArray = [[NSMutableArray alloc] initWithCapacity: 3];
[dataArray insertObject:[NSMutableArray arrayWithObjects:#"0",#"0",#"0",nil] atIndex:0];
[dataArray insertObject:[NSMutableArray arrayWithObjects:#"0",#"0",#"0",nil] atIndex:1];
[dataArray insertObject:[NSMutableArray arrayWithObjects:#"0",#"0",#"0",nil] atIndex:2];
I hope you get your answer from the above example.
Cheers,
Raxit

This will also work:
NSArray *myArray = #[
#[ #1, #2, #3, #4],
#[ #1, #2, #3, #4],
#[ #1, #2, #3, #4],
#[ #1, #2, #3, #4],
];
In this case it is a 4x4 array with just numbers in it.

I'm not absolutely certain what you are looking for, but my approach to a two dimensional array would be to create a new class to encapsulate it. NB the below was typed directly into the StackOverflow answer box so it is not compiled or tested.
#interface TwoDArray : NSObject
{
#private
NSArray* backingStore;
size_t numRows;
size_t numCols;
}
// values is a linear array in row major order
-(id) initWithRows: (size_t) rows cols: (size_t) cols values: (NSArray*) values;
-(id) objectAtRow: (size_t) row col: (size_t) col;
#end
#implementation TwoDArray
-(id) initWithRows: (size_t) rows cols: (size_t) cols values: (NSArray*) values
{
self = [super init];
if (self != nil)
{
if (rows * cols != [values length])
{
// the values are not the right size for the array
[self release];
return nil;
}
numRows = rows;
numCols = cols;
backingStore = [values copy];
}
return self;
}
-(void) dealloc
{
[backingStore release];
[super dealloc];
}
-(id) objectAtRow: (size_t) row col: (size_t) col
{
if (col >= numCols)
{
// raise same exception as index out of bounds on NSArray.
// Don't need to check the row because if it's too big the
// retrieval from the backing store will throw an exception.
}
size_t index = row * numCols + col;
return [backingStore objectAtIndex: index];
}
#end

First you to have set An NSMutableDictionary on .h file
#interface MSRCommonLogic : NSObject
{
NSMutableDictionary *twoDimensionArray;
}
then have to use following functions in .m file
- (void)setValuesToArray :(int)rows cols:(int) col value:(id)value
{
if(!twoDimensionArray)
{
twoDimensionArray =[[NSMutableDictionary alloc]init];
}
NSString *strKey=[NSString stringWithFormat:#"%dVs%d",rows,col];
[twoDimensionArray setObject:value forKey:strKey];
}
- (id)getValueFromArray :(int)rows cols:(int) col
{
NSString *strKey=[NSString stringWithFormat:#"%dVs%d",rows,col];
return [twoDimensionArray valueForKey:strKey];
}
- (void)printTwoDArray:(int)rows cols:(int) cols
{
NSString *strAllsValuesToprint=#"";
strAllsValuesToprint=[strAllsValuesToprint stringByAppendingString:#"\n"];
for (int row = 0; row < rows; row++) {
for (int col = 0; col < cols; col++) {
NSString *strV=[self getValueFromArray:row cols:col];
strAllsValuesToprint=[strAllsValuesToprint stringByAppendingString:[NSString stringWithFormat:#"%#",strV]];
strAllsValuesToprint=[strAllsValuesToprint stringByAppendingString:#"\t"];
}
strAllsValuesToprint= [strAllsValuesToprint stringByAppendingString:#"\n"];
}
NSLog(#"%#",strAllsValuesToprint);
}

Hope this helps.
This is just example how you can initial 2d array of int in code (Objective C works)
int **p;
p = (int **) malloc(Nrow*sizeof(int*));
for(int i =0;i<Nrow;i++)
{
p[i] = (int*)malloc(Ncol*sizeof(int));
}
//put something in
for(int i =0;i<Nrow;i++)
{
p[i][i] = i*i;
NSLog(#" Number:%d value:%d",i, p[i][i]);
}
//free pointer after use
for(int i=0;i<Nrow;i++)
{
p[i]=nil;
//free(p[i]);
NSLog(#" Number:%d",i);
}
//free(**p);
p = nil;

Related

Remove Every Other Element

I have a large array (which I want to graph), and I want to reduce the size of it by removing every other element in it. If I have an array like:
NSMutableArray *array = [[NSMutableArray alloc] initWithObjects:#"Hello", #"Again", #"World", #"I", #"Test", #"All-Day", nil];
How would I be able to get it down to:
(Hello, World, Test)
Any solution involving removeObjectAtIndex: is O(N^2), which you might not want since you said you “have a large array”.
#interface NSMutableArray (FG8_removeOddElements)
- (void)removeOddElements;
#end
#implementation NSMutableArray (FG8_removeOddElements)
- (void)removeOddElements {
// Given (a, b, c), result is (a, c), so round up.
NSUInteger finalCount = (self.count + 1) / 2;
// Element 0 never moves so start at 1.
for (NSUInteger i = 1; i < finalCount; ++i) {
self[i] = self[i * 2];
}
[self removeObjectsInRange:NSMakeRange(finalCount, self.count - finalCount)];
}
#end
Assuming removeObjectsInRange: is efficient, this performs the work in O(N) time.
UPDATE
Since HotLicks seems to think this algorithm doesn't work, here's a test:
#implementation AppDelegate
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
NSMutableArray *array = #[#"a", #"b", #"c", #"d", #"e", #"f", #"g"].mutableCopy;
[array removeOddElements];
NSLog(#"%#", array);
}
#end
And here's the output:
2014-05-08 15:23:44.123 tester[43347:303] (
a,
c,
e,
g
)
Use a function like this:
- (NSMutableArray *)removeEveryOtherElement:(NSMutableArray *)array
{
NSLog(#"Input array: %#", array);
NSMutableArray *returnArray = [[NSMutableArray alloc] init];
for (int x = 0; x<=array.count - 1; x++) {
if (x % 2 == 0) { // if the index of the object is "even" (divisible by 2)
[returnArray addObject:[array objectAtIndex:x]];
}
}
NSLog(#"Returned array: %#", returnArray);
return returnArray;
}
You have to watch out, because if you're performing operations on an NSMutableArray the indices will change as you're adding and removing objects (thus the problem with my first answer).
Output:
2014-05-08 16:14:14.693 test[2013:303] Input array: (
0,
1,
2,
3,
4,
5
)
2014-05-08 16:14:14.693 test[2013:303] Returned array: (
0,
2,
4
)

Printing a string object from an NSMutableArray

I stored some strings in objects and added the objects to an NSMutableArray. Now I want to print the strings in each element of the array. Clearly, I'm doing something wrong. I'm going to back and review these basics, but I was hoping someone could explain how I can print the string instead of the what looks to be the element address.
/** interface **/
#property (nonatomic, copy) NSString*myNumber;
-(void)setNumber: (NSString*) randomNumber;
/** implementation **/
#synthesize myNumber;
-(void) setNumber:(NSString *)randomNumber
{
myNumber = randomNumber;
}
/**main**/
Fraction * aFrac = [[Fraction alloc] init];
[aFrac setNumber:#"5/6"];
Fraction * bFrac = [[Fraction alloc] init];
[bFrac setNumber:#"2/3"];
NSMutableArray * myArray = [[NSMutableArray alloc] init];
[myArray addObject:aFrac];
[myArray addObject:bFrac];
int i;
for(i = 0; i<2; ++i)
{
id myArrayElement = [myArray objectAtIndex:i];
NSLog(#"%#", myArrayElement);
}
for(i = 0; i<2; ++i)
{
NSLog(#"%#", myArray[i]);
}
Both for loops print the same thing.
When you pass a custom object to NSLog you have to override the -(NSString)description method in that object.
So in your Fraction class if you simply override this function like so
- (NSString*)description
{
return self.myNumber;
}
that should log out what you want.
I would probably think about renaming that property from number as you are storing a string.
Hope that helps
I'm guessing the Fraction type you created has a NSString property or method named number (to match the -setNumber: method), in which case you would use the following code to print it:
NSLog("%#", [myArrayElement number]);
Or, for the second loop:
NSLog("%#", [myArray[i] number]);
In your code both for loop meaning has same only, try below
for(i = 0; i<2; ++i)
{
id myArrayElement = [myArray objectAtIndex:i];
NSLog(#"%#", myArrayElement.number);
}
for(i = 0; i<2; ++i)
{
NSLog(#"%#", myArray[i].number);
}
Now here two array value you are extracting
[myArray objectAtIndex:i] which is equivalent to myArray[i]

Self and arrays problems

I am new to Objective C and I'm having trouble getting my head around a few things.
I am trying to make a big integer program, from which I read items entered in a string and put them into an individual elements in the array.
I am currently working on an add method which adds elements from both the arrays together to make a big number stored in a final array.
But I'm kind of confused about to get this array I made from the initWithString method into the array method. I have some understanding of self, but I don't really know how to use it in this sense.
#implementation MPInteger
{
}
-(id) initWithString: (NSString *) x
{
self = [super init];
if (self) {
NSMutableArray *intString = [NSMutableArray array];
for (int i = 0; i < [x length]; i++) {
NSString *ch = [x substringWithRange:NSMakeRange(i, 1)];
[intString addObject:ch];
}
}
return self;
}
-(NSString *) description
{
return self.description;
}
-(MPInteger *) add: (MPInteger *) x
{
//NSMutableArray *arr1 = [NSMutableArray arrayWithCapacity:100];
//NSMutableArray *arr2 = [NSMutableArray arrayWithCapacity:100];
//for (int i=0; i < 100; i++) {
//int r = arc4random_uniform(1000);
//NSNumber *n = [NSNumber numberWithInteger:r];
//[arr1 addObject:n];
//[arr2 addObject:n];
// }
self.array = [NSMutableArray initialize];
return x;
}
#end
int main(int argc, const char * argv[]) {
#autoreleasepool {
MPInteger *x = [[MPInteger alloc] initWithString:#"123456789"];
MPInteger *y = [[MPInteger alloc] initWithString:#"123456789"];
[x add: y];
}
}
So I want too add the x and y arrays, but I'm not sure how to get the arrays in the add method. Do I use self to represent one of the arrays and initialise it, and x to represent the other. I don't know if I'm going about it completely the wrong way. Some help to understand would be greatly appreciated.
When referring to self you're actually accessing the current instance of the class. In other languages this may be implemented as this instead. There are a couple ways of designing the approach you're going for but the simplest pattern is probably composition:
#interface MPInteger
{
NSMutableArray *digits;
}
#end
----------------------------------------------------------------------------
#implementation MPInteger
-(id) initWithString: (NSString *) x
{
// Create a new instance of this class (MPInteger) with a default
// constructor and assign it to the current instance (self).
self = [super init];
if (self) {
// Previously we initialized a string, but then threw it out!
// Instead, let's save it to our string representation:
self->digits = [NSMutableArray array];
for (int i = 0; i < [x length]; i++) {
NSString *ch = [x substringWithRange:NSMakeRange(i, 1)];
[self->digits addObject:ch];
}
return self;
}
// Depending on how you want to implement this function, it could return
// a new MPInteger class or update the current instance (self):
-(MPInteger *) add: (MPInteger *) x
{
NSArray *a = self->digits;
NSArray *b = x->digits;
// Have both strings for A + B, so use them to find C:
NSArray *c = ????;
// Return a new instance of MPInteger with the result:
return [ [ MPInteger alloc ] initWithString:c ];
}
#end
Notice that now the MPInteger class has an instance of an NSString object that will exist during the entire lifetime of the MPInteger object. To update/access this string, all you need to do is say:
self->digits

Reversing "columns" in a table made from a NSArray

I have a NSArray made out of numbers 1..50, which represents a table with columns & rows.
I need to reverse only the order of the columns, while keeping the order of the rows.
So for example:
0,1,2,3,4,5,6
7,8,9,9,10,11,12
has to be
6,5,4,3,2,1,0
12,11,10,9,8,7
Right now, i use a huge IF statement for that:
for (dd *d in dates[i]) {
if (tileNum==0) {
reversedTileNum = 6;
} else if (tileNum==1) {
reversedTileNum = 5;
}else if (tileNum==2) {
reversedTileNum = 4;
}else if (tileNum==3) {
reversedTileNum = 3;
}else if (tileNum==4) {
reversedTileNum = 2;
}else if (tileNum==5) {
reversedTileNum = 1;
} else if (tileNum==6) {
reversedTileNum = 0;
}
....
....
}
Here's a solution that should be easy to drop into any project. It involves two categories: one on NSMutableArray that provides a method to swap objects at two indices, and one on NSArray that provides the -arrayByReversingGroups: method. The idea is to swap the elements in pairs within a group, reversing the group. If number of elements in the array isn't an even multiple of groupSize, the extras at the end are left untouched.
The code presented here is a complete program, so you can see an example of using -arrayByReversingGroups: in the main() function.
#import <Foundation/Foundation.h>
#interface NSArray(Reversible)
-(NSArray*)arrayByReversingGroups:(int)groupSize;
#end
#interface NSMutableArray(Swappable)
-(void)swapObjectAtIndex:(int)first withObjectAtIndex:(int)second;
#end
#implementation NSArray(Reversible)
-(NSArray*)arrayByReversingGroups:(int)groupSize
{
NSMutableArray *newArray = [self mutableCopy];
// Iterate over the array in chunks of groupSize elements. i will be first index in
// the current chunk.
for (int i = 0; (i + groupSize) < [newArray count]; i += groupSize) {
// Iterate over the items in the current chunk, swapping the bth and
// (groupsize-b-1)th elements until they meet at groupsize/2.
for (int b = 0; b <= (groupSize / 2); b++) {
int first = i + b;
int second = i + groupSize - b - 1;
[newArray swapObjectAtIndex:first withObjectAtIndex:second];
}
}
return [newArray copy];
}
#end
#implementation NSMutableArray(Swappable)
-(void)swapObjectAtIndex:(int)first withObjectAtIndex:(int)second
{
id temp = [[self objectAtIndex:second] retain];
[self replaceObjectAtIndex:second withObject:[self objectAtIndex:first]];
[self replaceObjectAtIndex:first withObject:temp];
[temp release];
}
#end
int main (int argc, const char * argv[])
{
#autoreleasepool {
NSArray *array = [NSArray arrayWithObjects:
#"1", #"2", #"3", #"4", #"5", #"6", #"7", #"8", #"9", #"10", #"11", #"12", nil];
NSLog(#"Original: %#", array);
NSLog(#"Reversed: %#", [array arrayByReversingGroups:5]);
}
return 0;
}
I can give you the logic.. you will have to write the code...
First create a function where you pass in an array(here you will send in a row.) then in this function create a new tempeorary array and store all the values for that row in this column then overwrite the original array in reverse order from this new array and return this to the full matrix and store it in there ... hope it helps.

printing an array of arrays in objective C

Sorry for the simple question, but I am self taught and know that there are gaps in my education.
To print an array in objective C, I believe is:
NSLog(#"My array: %#", myArray);
How can I print an array of arrays?
Thanks
You want this:
for(NSArray *subArray in myArray) {
NSLog(#"Array in myArray: %#",subArray);
}
This will work for an array that has arrays nested one level deep.
You don't need to do anything different to log an array of arrays; the code exactly as you've written it will already show the contents of the sub-arrays.
That is, the following program:
#import <Foundation/Foundation.h>
int main (int argc, const char * argv[]) {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
NSMutableArray *array = [NSMutableArray array];
for (int i=0; i<5; ++i) {
NSMutableArray *sub = [NSMutableArray array];
for (int j=0; j<=i; ++j) {
[sub addObject:[NSString stringWithFormat:#"%d", j]];
}
[array addObject:sub];
}
NSLog(#"Array: %#", array);
[pool drain];
return 0;
}
Produces the following output:
Array: (
(
0
),
(
0,
1
),
(
0,
1,
2
),
(
0,
1,
2,
3
),
(
0,
1,
2,
3,
4
)
)
Clearly, it's already logging the sub-arrays just fine. If you want to control the formatting differently, you'd have to manually iterate them, but by default, the -description of an NSArray is little more than the -description of every object in that array, which includes all sub-arrays.
So I was embarrassed by the recursiveDescription thing, so I wrote my own as a category on NSArray. Note that this code will print out a description for an array of arrays to any depth. The description itself could probably use a bit more formatting than commas and newlines. Here you go:
#interface NSArray (RecursiveDescription)
- (NSString *)recursiveDescription;
#end
#implementation NSArray (RecursiveDescription)
- (NSString *)recursiveDescription {
NSMutableString *description = [[NSMutableString alloc] initWithString:#"Array (\n"];
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
for (NSObject *child in self) {
if ([child respondsToSelector:#selector(recursiveDescription)]) {
[description appendFormat:#"%#,\n", [child recursiveDescription]];
}
else {
[description appendFormat:#"%#,\n", [child description]];
}
}
[pool drain];
[description appendString:#"\n)"];
return [description autorelease];
}
#end
Try logging the return value from NSArray's -description method.
NSLog(#"My array: %#", [myArray description]);
Moreover, for print all of elements
int i = 0;
int j = 0;
for(NSArray *subArray in myArray) {
NSLog(#"[%d] %#",i, subArray);
j =0;
for(NSObject *element in subArray) {
NSLog(#"[%d:%d] %#", i,j,element);
++j;
}
++i;
}
As much as I like how easy it is to log out an object in Objective-C, I didn't like seeing a 2D array as a very long list. I created a category on NSArray that prints out 2D arrays. It's not perfect and can be improved, but it has worked for me.
Header:
#interface NSArray (Logging)
- (void)log2DArray;
#end
Implementation:
#import "NSArray+Logging.h"
#implementation NSArray (Logging)
- (void)log2DArray {
NSMutableString *formattedString = [[NSMutableString alloc] init];
NSInteger longestSubarrayLength = 0;
for (NSArray *subarray in self) {
if (subarray.count > longestSubarrayLength) {
longestSubarrayLength = subarray.count;
}
}
for (int i = 0; i < longestSubarrayLength; i++) {
[formattedString appendFormat:#"\n"];
for (int j = 0; j < self.count; j++) {
NSArray *tempArray = [self objectAtIndex:j];
if (tempArray.count <= longestSubarrayLength) {
[formattedString appendFormat:#"%#\t", [tempArray objectAtIndex:i]];
} else {
[formattedString appendFormat:#"\t"];
}
}
}
NSLog(#"%#", formattedString);
}
#end
Usage:
[myArray log2DArray];
Or use recursiveDescription :)
NSLog(#"my arrays: %#", [myArray recursiveDescription]);