resolution of the following error? - c#

private static void VisualizarAgendaOrdenada()
{
Pacientes.Sort();
for(int i = 0; i <= Pacientes.Count; i++)
{
var agenda = Agendas.Find(p => p.Paciente.Nome == Pacientes[i].Nome);
if (agenda != null)
{
Error,
"Index is out of bounds. Index cannot be negative or greater than the size of the collection."

Your loop condition is wrong: you may not loop until <= Pacientes.Count, but only until < Pacientes.Count.
for (int i = 0; i < Pacientes.Count; i++)
Otherwise you will try to access an index that is outside the range of the list. A list with Count elements is indexed from 0 to Count-1.

You're trying to read from the list under index which does not exist. Change your <= to <.
for(int i = 0; i < Pacientes.Count; i++)
Because arrays/lists are indexed starting from 0 when you need to iterate over all elements you always have to use < Count() or < Length.

Related

Does "for loop" needs to start at 0 when we are trying to assign the number to array which we get it from user?

I am having a issue which related to loops.
int[] numbers= new int[5];
for (int i = 0; i < 5; i++)
{
Console.WriteLine("Enter a number: ");
numbers[i] = Convert.ToInt32(Console.ReadLine());
}
Array.Sort(numbers);
foreach (int i in numbers)
{
Console.WriteLine(i);
}
Console.ReadLine();
İf i try to change the for (int i = 0; i < 5; i++) to for (int i = 1; i < 6; i++).
It gives me:System.IndexOutOfRangeException: 'Index was outside the bounds of the array.'.
What is the difference between these two?
int i=0; i<5; i++ => 0->1->2->3->4 Length of array:5
int i=1; i<6; i++ => 1->2->3->4->5 Length of array:5
if your array has 5 elements the highest index is 4, as array-indices (and lists also) are zero-based.
In order to iterate all elements in an array you should therefor start at zero and stop at Length - 1. In your case that means go from zero to 4 as in your first loop.
The second loop starts at 1 and goes to 5. As 5 is not a valid index in the array (remember, it has 5 elements, but the highest index is 4), you get the exception.
Afterall you can also define for-loops from any arbitrary start-index. For example you can reverse the loop:
for(int i = array.Length - 1; i >= 0; i--) { ... }
Or you can take just the second through the fourth item:
for(int = 1; i < 4; i++) { ... }
You can also iterate the numbers from -5 to 10, that are completely unrelated to any array:
for(int i = -5; i < 10; i++) { ... }
So in short: a for-loop does not assume any specific start. However when iterating collections you have to ensure you stay within their bounds which are zero-based.

Bring multiple 2d arrays [][] on same length

i have a huge Problem when dealing with jagged arrays [][].
I wrote a program that interacts with lots of CSV-files. It will read them and then compare them. Now i have a problem if Array A has the dimension of 10 Rows and 10 Columns but Array B only has the dimension of 5 Rows and 5 Columns. I get the "out of range" on array B. This is only an example it gets even worse if i have a array which has different amount of Rows in each Column...
I tried checking for "null" but this doesnt work since i get the "out of range" once it tries to acess the field...
Now i have 2 theories to solve the problem:
A.)Check for "out of range" in Array B and if so fill Array A at the same field with a "0"
B.) Check if Array A and Array B has same dimension and if not fill the array with lesser amount with "0" so that it has the same amount
On both solutions i have absolutely no clue how to do this in C#... I am always getting the out of range...
What i currently do for 1 array is:
for (int b = CSV_Statistiken.Length - 1; b >= 0; b--)
{
for (int a = 0; a < CSV_Statistiken[b].Length; a++)
{
CSV_Statistiken[b][a] = 1;
}
}
so i get the dimension of the array and iterate through it, setting every value to 1. But how do i deal with my problem with 2 arrays?
I researched a bit but couldnt find any solution to this =/
Thanks in advance
Edit: What i am trying to do for examlple:
for (int i = 0; i < number; i++) //runs through every File existing
{
NextFile = fold.Filepath + "\\" + files[i].ToString();
file = new FileInfo(#NextFile);
max_Rows = 0;
max_Col = 0;
CSV_temp = ReadCSV(file, ref max_Rows, ref max_Col); // reads the next file to an arraay [][] and saves the size of this array in max_col/ max_rows
MAX_Col_Total = GetHighestValues(ref MAX_Col_Total, max_Col);
MAX_Rows_Total = GetHighestValues(ref MAX_Rows_Total, max_Rows);
for (int j = 0; j < MAX_Col_Total; j++) //runs thrugh the max amount of cols found
{
for (int k = MAX_Rows_Total - 1; k >= 0; k--) //runs through the max mount of rows found
{
if (CSV_temp.GetLength(0) >= j && CSV_temp.GetLength(1) >= k)//Checks if Field exists -> does NOT work!
{
if (CSV_temp[k][j] > (Threshhold))) //
{
do something
}
}
else
{
// Field doesnt exists -> do something else
}
}
}
}
You can check Lengths of two arrays in for loops:
for (int a = 0; a < array1.Length && a < array2.Length; a++)
{
for (int b = 0; b < array1[a].Length && b < array2[a].Length; b++)
{
//compare
}
}
Now your loops never go outside of any array index and you won't get IndexOutOfRangeException.
EDIT:
var biggestLength1 = Math.Max(array1.Length, array2.Length);
for (int a = 0; a < biggestLength1; a++)
{
var biggestLength2 = 0;
if (array1.Length > a && array2.Length > a)
{
biggestLength2 = Math.Max(array1[a].Length, array2[a].Length);
}
else
{
biggestLength2 = array1.Length > a ? array1.Length : array2.Length;
}
for (int b = 0; b < biggestLength2; b++)
{
if (a < array1.Length &&
a < array2.Length &&
b < array1[a].Length &&
b < array2[a].Length)
{
// every array has enough elements count
// you can do operations with both arrays
}
else
{
// some array is bigger
}
}
}

Using variable value as for loop index

I have a code which contains 2 for loops:
for (int count = 0; list_Level[count] < list_Level[list_Level.Count]; count++)
{
for (int a = 0; list_Level[a] < Initial_Lvl; a++)
{
var dOpt = new DataGridObjectOpt();
double Closest_Goallvl = list_Level.Aggregate((x, y) => Math.Abs(x - Initial_Lvl) < Math.Abs(y - Initial_Lvl) ? x : y);
dOpt.ImageSource = new Uri(filePaths[a], UriKind.RelativeOrAbsolute);
dOpt.Level_Index = Initial_Lvl;
dOpt.Level_Goal = goallvl;
dOpt.Stage = 1;
LOpt_Temp.Add(dOpt);
}
count = a;
int best_Profit_Ind = LOpt_Temp.FindIndex(x => x.TotalCost == LOpt_Temp.Max(y => y.TotalCost));
LOpt.Add(LOpt_Temp[best_Profit_Ind]);
dataGridOpt.ItemsSource = LOpt;
}
I want the loops to begin at 0, however once the inner loop ends for the first time and ends at a value of a, i want the outer loop to begin from this place now.
For example, first loop begins at 0, inner loop exits when a=6. Now i want count to start for 6 and not 1.
Thank you.
As #dcg mentioned, do count+=a-1 before iterating again. As #dlatikay mentioned, you could run into IndexOutOfRangeException. To avoid that, add and condition in the outer for loop. So that your final code looks something like this:
for (int count = 0; list_Level[count] < list_Level[list_Level.Count] && count < list_Level.Count; count++)
{
for (int a = 0; list_Level[a] < Initial_Lvl; a++)
{
//Your code
}
count+=a-1
//Your code
}
Notice the middle condition in the outer for loop. Hope it helps.
First of all
list_Level[count] < list_Level[list_Level.Count]
by using this condition you will get IndexOutOfRangeException you should use
list_Level[count] < list_Level[list_Level.Count - 1]
something like that.
on the other hand this may help you:
for (int count = 0; list_Level[count] < list_Level[list_Level.Count - 1] && count < list_Level.Count; count++){
for (int a = 0; list_Level[a] < Initial_Lvl; a++)
{
//Your code
}
count = a-1;
if(count >= list_Level.Count)
{
break;
}
//Your code
}

Can't get my array loop right

I'm getting an Index was outside the bounds of the array.
string[] paths = {
"\\\\server\\c$\\folder\\subfolder\\user1\\300\\1\\abc.docx",
"\\\\server\\c$\\folder\\subfolder\\user2\\400\\1\\xyz.docx",
};
FileInfo[] f = new FileInfo[paths.Length];
for (int i = 0; i <= paths.Length; i++)
{
f[i] = new FileInfo(paths[i]);
Console.WriteLine(f[i].Length);
}
I can't seem to figure out why, any ideas?
use < instead of <=
for (int i = 0; i < paths.Length; i++)
{
f[i] = new FileInfo(paths[i]);
Console.WriteLine(f[i].Length);
}
Arrays start counting itens from 0. So, if you have an array with length 2, your objects will be in position [0] and [1]. If you try to access the position [2], you'll get the Index was outside the bounds of the array exception, because index 2 doesn't exist in this array.
In your for loop, you're using <= paths.Length. Your paths length is 2. 2 is less or equals 2, so your code will be executed like this
f[2] = new FileInfo(paths[2]) //Position 2 doesn't exist
To solve this, just change from:
for (int i = 0; i <= paths.Length; i++)
To:
for (int i = 0; i < paths.Length; i++)
You have two items in your array
paths[0], paths[1]
Your looping over three items
paths[0], paths[1], paths[2]
To correct this, change
for (int i = 0; i <= paths.Length; i++)
to
for (int i = 0; i < paths.Length; i++)

How can i check if the specific strings exist in a List<string> and if not to remove the indexs from the List?

I tried this but this is not working.
I'm getting index out of bound exception.
for (int x = 0; x < newText.Count; x++)
{
for (int y = 0; y < WordsList.words.Length; y++)
{
if (!newText[x].Contains(WordsList.words[y]))
{
for (int n = 0; n < 3; n++)
newText.RemoveAt(x);
}
}
}
newText is a List
words is string[]
newText format is like this:
index 0 = this is a text hello all
index 1 = time&date (6/14/2014....)
index 2 = empty ""
index 3 = text hello world
index 4 = time&date (6/14/2014....)
index 5 = empty ""
And so on...
What i want to do is to loop over newText and if in index 0 there no any word(string) from words then remove index 0,1,2 next itertion check index 3 for any words if not exist one word or more remove indexs 3,4,5.
If in index 0 or 3 there is one word or more then do nothing dont remove anything.
In the end newText should be in the same format as before:
index 0 text line
index 1 date&time
index 2 empty ""
Just the new newText content will be with text lines that contain one ore more strings from words.
EDIT
This is what i tried now:
First this is how i build the List:
List<string> t = filterNumbers(text);
for (int i = 0; i < t.Count; i++)
{
if (!newText.Contains(t[i]))
{
newText.Add(t[i]);
newText.Add(dateTime[i]);
newText.Add("");
}
}
Removing numbers and leave only text and add it.
In the end in this case i have in newText 150 indexs. That's 50 indexs of text lines.
Then i tried this:
int lastindex = newText.Count - 1;
for (int i = newText.Count - 1; i >= 0; i--)
{
for (int x = 0; x < WordsList.words.Length; x++)
{
if (!newText[i].Contains(WordsList.words[x]))
{
if (i != lastindex)
{
newText.RemoveAt(i + 1);
}
newText.RemoveAt(i);
}
}
}
But i'm getting exception on the line:
if (!newText[i].Contains(WordsList.words[x]))
Index was out of range. Must be non-negative and less than the size of the collection
EDIT
If I understood correctly that you wanted to check whether a specific line contains some words and if not remove that and the two following lines, here is a possible solution:
// start at the bottom in the first line "that matters" and go down by 3
for (int x = newText.Count - 3; x >= 0; x-=3)
{
// check if the line contains any of the words specified
if (!WordsList.words.Any(w => newText[x].Contains(w)) || newText[x] == "")
{
// remove the checked line as well as the next two if not
l.RemoveRange(x, 3);
}
}
EDIT
Corrected the predicate to:
!WordsList.words.Any(w => newText[x].Contains(w));
from
!WordsList.words.Any(w => newText.Contains(w));
EDIT 2
Added the empty string as possibility
The problem was that if the line to test was empty, it would pass the test because it does not contain any word from WordsList.words. The test now includes the empty string as an option and removes it when encountered.
Looking at your logic:
(1) for (int i = newText.Count - 1; i >= 0; i--)
{
(2) for (int x = 0; x < WordsList.words.Length; x++)
{
if (...)
{
(3) newText.RemoveAt(i);
}
}
}
You can see that even if you removed lines in (3), you continue loop in (2) which can try again remove line in (2) for new indexes, which now become out of bounds
you need to add break after (3) to continue loop (1)
// For each 3-word-sets
for (int x = 0; x < newText.Count; x += 3)
{
// For each word in that 3-word-set
for (int k = x; k < 3; k++)
{
// Check each word
bool breakOut = false;
for (int y = 0; y < WordsList.words.Length; y++)
{
if (!newText[k].Contains(WordsList.words[y]))
{
newText.RemoveAt(x+2);
newText.RemoveAt(x+1);
newText.RemoveAt(x);
x -= 3;
breakOut = true;
break;
}
}
if (breakOut) { break; }
}
}
I just wanted to test and experiment with your original code. Haven't tested this. Just make sure the list contains 3×n items.
Ok, it seems your data structure is really bad. Anyway if you have to keep the structure as is I think this can work :
var newList = new List<string>();
for (int index = 0; index < newText.Count; index = index + 3)
{
if (WordsList.Any(t => newText[index].ToLower().Trim().Contains(t.ToLower().Trim())))
{
newList.AddRange(newText.Skip(index).Take(3));
}
}
newText = newList;

Categories