Objective-C - Loop played but loop condition is false - objective-c

I'm trying to convert a sectionned table into a flat list using this function into didSelectRowAtIndexPath (I have a NSArray that is initialisated with the number of items contained in each section) :
Somewhere... :-)
self.sectionsArray = [NSArray arrayWithObjects:macroIntNumber(1), macroIntNumber(3), macroIntNumber(12), nil];
then into didSelectRowAtIndexPath :
int selectedRow = 0;
int a = indexPath.section;
for (int i=0; i<indexPath.section-1; i++) {
selectedRow += [[self.sectionsArray objectAtIndex:i] intValue];
}
selectedRow += indexPath.row;
But... This crashes for indexPath.section = 0 (first section).
Because the loop is played infinitly until crash of the NSArray call...
Strange !!!
forcing for (int i=0; i<0-1; i++) { works
forcing for (int i=0; i<a-1; i++) { works
What am I missing ?

section is an NSUInteger, so it's unsigned. Thus, subtracting 1 from 0 on that unsigned integer is taking you to a very large number rather than -1.
It works when using a, because you've declared a as an int. :)

Related

Converting NSString to array of chars inside For Loop

I'm trying to use an existing piece of code in an iOS project to alphabetize a list of words in an array (for instance, to make tomato into amoott, or stack into ackst). The code seems to work if I run it on its own, but I'm trying to integrate it into my existing app.
Each word I want it to alphabetize is stored as an NSString inside an array. The issue seems to be that the code takes the word as an array of chars, and I can't get my NSStrings into that format.
If I use string = [currentWord UTFString], I get an error of Array type char[128] is not assignable, and if I try to create the char array inside the loop (const char *string = [curentWord UTF8String]) I get warnings relating to Initializing char with type const char discards qualifiers. Not quite sure how I can get around it – any tips? The method is below, I'll take care of storing the alphabetized versions later.
- (void) alphabetizeWord {
char string[128], temp;
int n, i, j;
for (NSString* currentWord in wordsList) {
n = [currentWord length];
for (i = 0; i < n-1; i++) {
for (j = i+1; j < n; j++) {
if (string[i] > string[j]) {
temp = string[i];
string[i] = string[j];
string[j] = temp;
}
}
}
NSLog(#"The word %# in alphabetical order is %s", currentWord, string);
}
}
This should work :
- (void)alphabetizeWord {
char str[128];
for (NSString *currentWord in wordList)
{
int wordLength = [currentWord length];
for (int i = 0; i < wordLength; i++)
{
str[i] = [currentWord characterAtIndex:i];
}
// Adding the termination char
str[wordLength] = 0;
// Add your word
}
}
EDIT : Sorry, didn't fully understand at first. Gonna check this out.

iOS Objective-C - for-loop issue

The code below produces and error in the line [myArray objectAtIndex:i]; and I can't seem to figure out why?
Any ideas?
int total = 0;
for (int i = 0; i < myArray.count; i++) {
int tempNumber = [myArray objectAtIndex:i];
total = total + tempNumber;
}
It could be because you are setting an object to an int. By definition, objectAtIndex returns an object.
Depending on the type of object in myArray, you can try something like this:
int tempNumber = [[myArray objectAtIndex:i] intValue];
If you didn't put ints into your array, then you need to do something extra to get ints out. If you're getting an error with your code above, then it's because you don't have ints in the array, and you need
int myInteger = [[myArray objectAtIndex:i] intValue];
Or something to get the ints out of the array, depending on the rest of your code.

Dividing an array into separate arrays of four elements plus the reminder

I'm trying to divide an array into individual arrays of four elements, where the last array will contain the reminder. For example, if that main array's length property will be ten, three subarrays will be created - two consisting of four elements, and one of two elements.
The code I have right now looks like the following:
NSMutableArray *mainMutableArray = [NSMutableArray arrayWithObjects:#"First", #"Second", #"Third", #"Fourth", #"Fifth", #"Sixth", #"Seventh", #"Eighth", nil];
NSMutableArray *mutableArrayOfSubarrays = [NSMutableArray array];
int length = mainMutableArray.count / 4;
int location = 0;
for (int i = 0; i < length; i++)
{
[mutableArrayOfSubarrays addObject:[mainMutableArray subarrayWithRange:NSMakeRange(location, 4)]];
location += 4;
}
This of course works only when the reminder is equal to 0.
Any help would be greatly appreciated.
Ok, here we go:
int length = mainMutableArray.count;
for (int location = 0; location < length; location+=4)
{
unsigned int Size=length-location;
if (Size>4) Size=4;
[mutableArrayOfSubarrays addObject:[mainMutableArray subarrayWithRange:NSMakeRange(location, Size)]];
}
If you use a while loop, you can make the condition describe what you are actually trying to do:
NSUInteger length = [mainMutableArray count];
NSUInteger location = 0;
// Until the location is less than four away from the end
while( location <= (length - 4) ){
[mutableArrayOfSubarrays addObject:[mainMutableArray subarrayWithRange:NSMakeRange(location, 4)]];
location += 4;
}
// Pick up the remainder, if any
if( location != length ){
[mutableArrayOfSubarrays addObject:[mainMutableArray subarrayWithRange:NSMakeRange(location, length-location)]];
}
Loop from length*4 to mainMutableArray.count to get the remainder of the array.

Array of arrays with ints

How would you go about storing a 2 dimensional array of ints as a class variable?
If you want an array of ints you go:
Class declaration
int * myInts;
Implementation
int ints[3] = {1,2,3};
myInts = ints;
But what if you want to store an array of arrays with ints?
Like this:
int ints[3][3] = {{1,2,3}, {1,2,3}, {1,2,3}};
I don't wanna limit the size of the arrays in the class declaration so I guess I have to go with pointers, but how?
For future reference, this is my conclusion:
Class declaration
int ** ints;
Implementation
int rows = 2;
int cols = 5;
ints = (int**)malloc(rows*sizeof(int*));
ints[0] = (int*)malloc(cols*sizeof(int));
ints[0][0] = 123;
ints[0][1] = 456;
ints[0][2] = 789;
// etc
This is my own interpretation of links provided in comments and my C skills are pretty low so take that into consideration ;) Maybe there are better ways to put in multiple numbers at a time with {123,456,789} or something, but that is beyond my requirements for now!
I've wrote sample for you:
int N = 10, M = 15;
NSMutableArray *ints = [NSMutableArray arrayWithCapacity:N]; // array[N][M]
for (int i=0; i<N; i++)
{
NSMutableArray *arr = [NSMutableArray arrayWithCapacity:M];
for (int j=0; j<M; j++)
{
[arr addObject:[NSNumber numberWithInt:(i+1)*(j+1)]];
}
[ints addObject:arr];
}
// print
for (int i=0; i<[ints count]; i++)
{
NSString *line = #"";
NSMutableArray *arr = [ints objectAtIndex:i];
for (int j=0; j<[arr count]; j++)
line = [NSString stringWithFormat:#"%# %#", line, [arr objectAtIndex:j]];
NSLog(#"%#", line);
}
If you want to dynamically allocate memory, in other words define the size of the arrays at runtime, then you need to declare the array as a pointer, malloc it, and then add another array of ints to each index at runtime. You can't really declare and dynamically allocate at the class level. If you are using cocoa/iphone sdk you can use NSMutableArray.
You could also create your own class that constructs a two dimensional array and exposes methods to push and pop int objects like [IntegerArray push:x,y,n];
Here's and example of using a double reference as Daniel R Hicks pointed out.

Array giving EXC_BAD_ACCESS in for loop

I have a C array defined in my method as:
int c = 4;
int r = 5;
keysArray[c][r];
I have this for loop, which works, populating the keysArray as expected.
for (int row = 0; row < r; row++) {
for (int column = 0; column < c; column++){
keysArray[column][row] = [anotherArray objectAtIndex:0];
NSLog(#"array1 %#",keysArray[column][row]);
[anotherArray removeObjectAtIndex:0];
}
}
Then in a for loop underneath, featuring exactly the same looping counter structure, when i try to NSLog the array, it gives an EXC_BAD_ACCESS.
for (int row = 0; row < r; row++){
for (int column = 0; column < c; column++) {
NSLog(#"array2: %#",keysArray[column][row]); //EXC_BAD_ACCESS here
}
}
What would cause this to happen, given that the keysArray is defined in the method body, outside of both sets of loops?
Are the contents of anotherArray retained by some other object? If not, they do not exist anymore in the second loop. WTH are you using a C array to store Objective-C objects anyway?
int c = 4;
int r = 5;
NSMutableArray *keysArray = [[NSMutableArray alloc] initWithCapacity:c];
for (int column = 0; column < c; column++) {
[keysArray addObject:[NSMutableArray arrayWithCapacity:r]];
for (int row = 0; row < r; row++) {
[[keysArray objectAtIndex:column] addObject:[anotherArray objectAtIndex:0]];
[anotherArray removeObjectAtIndex:0];
}
}
for (int row = 0; row < r; row++){
for (int column = 0; column < c; column++) {
NSLog(#"array2: %#", [[keysArray objectAtIndex:column] objectAtIndex:row]);
}
}
You need to retain the objects held in your C array. Unlikes an NS*Array, a C array does not retain on adding to the array.
However, for a no-holes 2D array like that, I'd just use a single NSMutableArray. Any N-dimensional array can be represented as a line-- as a one dimensional array-- with simple math.
Namely, to determine the index of an object at (X,Y), use (Y * width) + X).
The only caveat is that NS*Array does not support "holes". You will need to fill the array row by row. That is, for a 3x4 (3 wide, 4 tall) array, you would fill it in the order 0,0, 1,0, 2,0, 0,1, 1,1, etc...
Obviously, insert and remove operations will mess up your 2D representation (but they would in an NSMutableArray of NSMutableArrays, too).
Alternatively, use NSPointerArray as it can have holes.
Could this be the problem :
[anotherArray removeObjectAtIndex:0];
try
keysArray[column][row] = [[anotherArray objectAtIndex:0] retain];
although if I were you I would use NSMutableArray of NSMutableArray instead