Array in for loop gives array index out of range exception - c#

Here is my code:
ShopButton[] allButtons = FindObjectsOfType<ShopButton> ();
for (int i = 0; i < allButtons.Length; i++)
{
allButtons [i].UpdateButtonState ((GameDataManager.publicInstance.skinAvailability & 1 << allButtons [i - 1].ninjaNumber) == 1 << allButtons [i - 1].ninjaNumber);
}
When I run it this code gives me an IndexOutOfRangeException.

I think the reason is because of the first index that causes a problem.
if i starts with 1 then i-1 will be 0 and therefore the index 0 exists in array allbuttons.
Clearly : if starting i is 0, then i-1 will be -1; this will cause index out of range exception because all arrays start with index 0 and have no index -1. ;
Starting with i = 1 the error will be solved because then i-1 will be 0 which is in range of indexes of any array.
change part of loop to :
for (int i = 1; i < allButtons.Length; i++)

Related

For-loops, array and ++ operator

Beginner asking a question.
I am testing the increment ++ operator within for-loop and the outcome is different than I expect it to be and I have no clue why. The code is not for a specific program.
int[] numbers = new int[10];
for (int i = 0; i < 10; i++)
{
numbers[i] = i++;
}
for (int a = 0; a < 10; a++)
{
Console.WriteLine("value is {0} at position {1}", numbers[a], a);
}
Output is:
value is 0 at position 0
value is 0 at position 1
value is 2 at position 2
value is 0 at position 3
value is 4 at position 4
value is 0 at position 5
value is 6 at position 6
value is 0 at position 7
value is 8 at position 8
value is 0 at position 9
If i run the first for-loop without the ++ increment (numbers[i] = i;), the values are consecutive and in order (0, 1, 2, 3 etc.). Why the ++ increment causes every other value to be zero? I thought it would be something like 0, 2, 4, 6, 8, 10 etc.
If I run numbers[i] = i+1;
outcome is something I would expect:
value is 1 at position 0
value is 2 at position 1
value is 3 at position 2
value is 4 at position 3
value is 5 at position 4
value is 6 at position 5
value is 7 at position 6
value is 8 at position 7
value is 9 at position 8
value is 10 at position 9
The code you write is
for (int i = 0; i < 10; i++)
{
numbers[i] = i++;
}
that is equal to
for (int i = 0; i < 10; i++)
{
numbers1[i] = i;
i = i + 1;
}
First time i is start from 0
// I change the i to real value for easy understanding
for (int i = 0; i < 10; i++)
{
numbers1[0] = 0;
i = 0 + 1;
//so here i is 1
}
Second time i is 2, because after first time loop the i is 1 then the for (int i = 0; i < 10; i++) will increase i from 1 to 2,
so the second time loop will be
for (int i = 0; i < 10; i++)
{
numbers1[2] = 2;
i = 2 + 1;
//so here i is 3
}
So now you know the numbers[0] is 0 and numbers[2] is 2 but about the numbers[1] you don't set the value for it so it will be the default value which the default value of int is 0.
Thank you Michael! I verified that out also by myself when messing around with the code. First I tried adding one more i++;
for (int i = 0; i < 50; i++)
{
numbers[i] = i++;
i++;
}
It gave me value on every third row.
And then third i++:
for (int i = 0; i < 50; i++)
{
numbers[i] = i++;
i++;
i++;
}
Now value every fourth line.
Solved.

List< string > to string[,]

I have a List<string> tmpNames that contains names e.g. ("A","B","C","D","E",F").
The size of tmpNames can be different (it is a result obtained from client input).
Now I need to create a matrix with a number of rows and columns.
string[,] tmpMatrix = new string[tmpRows.Count,tmpCols.Count];
But to iterate and build the matrix I have the following code in which I can not access all items in tmpNames.
for(int i= 0; i<tmpRows.Count; i++){
for(int j= 0; j<tmpRows.Count; j++){
tmpMatrix[i,j] = tmpNames[i];
}
}
The result that I need is:
A B C
D E F
You have to calculate which index you need from tmpNames - you need both i and j for that. You might want to put it on paper to see the pattern:
j=0 j=1 j=2
i=0 0 1 2
i=1 3 4 5
Your code should be something like:
for(int i= 0; i<tmpRows.Count; i++){
for(int j= 0; j<tmpCols.Count; j++){
tmpMatrix[i,j] = tmpNames[i * tmpCols.Count + j];
}
}
Note that I have also corrected the condition in the 2nd loop: you have to compare j with tmpCols.Count, not tmpRows.Count.
You could use separate indexes for Row, Column & source:
for(int i = 0, source = 0; i < tmpRows.Count; i++){
for(int j = 0; j < tmpCols.Count; j++){
tmpMatrix[i, j] = tmpNames[source++];
}
}
You can calculate the indexes in the tmpMatrix from the index in the tmpNames list and populate it using a single loop:
int index = 0;
for (int index = 0; index < tmpNames.Count; index++) {
tmpMatrix[index / tmpCols.Count, index % tmpCols.Count] = tmpNames[index];
}
By using divison and modulo (%) you get the result as row and reminder as column:
index index / 3 index % 3
----- --------- ---------
0 0 0
1 0 1
2 0 2
3 1 0
4 1 1
5 1 2

Copying a smaller array into a larger one

I'm struggling to think of the most elegant/simple way of doing this. Perhaps I'm overthinking it a little.
Lets say I've got a 5x5 array of integers that looks like this:
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
And another 2x2 array of integers that looks like this:
5 1
2 3
I want to pick a location in the 5x5 array, say [2][2], and place the values from the second array into the first, so it looks like this:
0 0 0 0 0
0 0 0 0 0
0 0 5 1 0
0 0 2 3 0
0 0 0 0 0
My initial thought was to use a for loop after determining the number of rows/columns in the array to be copied, but I can't seem to puzzle out a way in my head to do that this morning.
Any suggestions?
Edit:
Sorry, here's the way I'm doing it currently. Just wondering if there's a better way.
This is actually part of a unity thing I'm doing - "RoomDoors" is our smaller array, and "map" is the larger array it's being moved into. It's part of a random map generator that needs to know which "edges" of tiles in rooms have doors on them that can connect to other rooms. RoomDoors stores 4 booleans, one for each direction telling me if there's a door there.
roomDoors = previousRoom.GetComponent<RoomDataInterface> ().rooms; //2d array of room/door arrangement in new room
sizeCol = roomDoors.GetLength (0);
sizeRow = roomDoors.GetLength (1);
map [10, 10] = roomDoors [0, 0]; // top left of the room goes in the spot
for (int i = 0; i < sizeCol; i ++){
for (int j = 0; j < sizeRow; j ++) {
map [i + 10,j + 10] = roomDoors[i,j];
}
I think you can't do much better, just remove the unnecessary assignment:
roomDoors = previousRoom.GetComponent<RoomDataInterface> ().rooms;
sizeCol = roomDoors.GetLength (0);
sizeRow = roomDoors.GetLength (1);
for (int i = 0; i < sizeCol; i ++)
for (int j = 0; j < sizeRow; j ++)
map [i + 10, j + 10] = roomDoors[i, j];
The line
map [10, 10] = roomDoors [0, 0];
is redundant, as the same assignment will be performed by the first iteration of the loop. Removal of the line will result in a solution that is smaller and more efficient.

C# & VS error: "make sure that the maximum index on a list is less than the list size"

I faced the error mentioned in the title when doing my homework, and simply can't find a way to remove it. Here is the method that I have this problem with:
public static double LaskeMiidi(double[] luvut)
{
double ka = Keskiarvo(luvut);
double miidi = luvut[0];
for (int i = 0; i < luvut.Length; i++)
{
if (luvut[i] - ka < luvut[i + 1] - ka) // The line error points to!
{
miidi = luvut[i];
}
else
{
miidi = luvut[i + 1];
}
}
return miidi;
}
So basically the problem is that when I say luvut[i + 1], at some point this index might become more than the length of the array is. I just can't figure out any ways to solve this problem, since I'm only a beginner with programming.
Yes, this is the problem:
for (int i = 0; i < luvut.Length; i++)
{
if (luvut[i] - ka < luvut[i + 1] - ka)
When i is luvut.Length - 1, then i + 1 will be luvut.Length - and therefore an invalid index. (For an array of length x, the valid indexes are 0 to x - 1 inclusive.) You probably want to end one iteration earlier:
for (int i = 0; i < luvut.Length - 1; i++)
That way i + 1 will still be a valid index in the array - both in the if condition and in the body of the else clause.
End your loop earlier:
for (int i = 0; i < luvut.Length - 1; i++)
This stops the loop ever getting to the point where an index would be invalid.
When i = luvut.Length -1, luvut[i + 1] will give an error as it is beyond the array bounds.
You need either:
for (int i = 0; i < luvut.Length - 1; i++)
Or else handle the luvut[i + 1] issue in another way in another If block.
Notice that when you define an array, range of items are between 0 and array.length-1. so you should write:
for (int i = 0; i < luvut.Length-1; i++)

Index was outside the bounds of the array

Friends
I have got an error which tells "Index was outside the bounds of the array" I dont know y it was happening since after completeting the for loop and entering the loop fresh again it was showing the variable value when exited from the loop before.
int[,] arrScr = new int[lstTest.Count, cnt2 + 3];
string[,] arrName = new string[lstTest.Count, cnt2 + 3];
int p;
for (i = 0; i < lstTest.Count; i++)
{
using (DataTableReader dtr3 = ds.Tables["scord_mark_table" + (i + 1).ToString()].CreateDataReader())
{
p = 0;
while (dtr3.Read())
{
arrName[i, 2 + p] = dtr3[15].ToString();
for (int k = 2; k < 12; k++)
{
arrScr[i, 2 + p] += Convert.ToInt32(dtr3[k].ToString());
}
p++;
}
}
What is in dtr3[12]? does it return null?
What is the value of cnt2?
Change k <= 12 to k < 12.
If this is not the cause of your problem you should rewrite k <= 12 to k < 13 as that is the convention most coders are used to read and write.
This means that your array does not contain as many elements as you are trying to access.
It's going to exit from the loop as k = 13 because the last valid value of k is 12, then it went through the loop, executed k++ (making it 13). At which point it fails the condition because 13 > 12 and that's when it actually exits.

Categories

Resources