C# copy values from array to list - c#

I have following code:
for (int c = 0; c < date_old.Length; c++)
{
for (int d = 0; d < date_new.Length; d++)
{
newList[c] = data_old[c];
if (date_old[c] == date_new[d])
{
newList[c] = data_new[d];
}
}
}
What I'm trying to do is the following:
I have four arrays: date_new, date_old, data_new, data_old and a List called newList.
date_old and data_old have the same length and date_new and data_new too.
I want to loop through the date arrays check if there are equal date values. While I'm doing this, I want to copy every value from the data_old array to newList. When a value is equal, I want to copy the value at this point from the data_new position into the List.
Here I get a OutOfBoundException after the second for loop. What is wrong?

Make sure your newList is instantiated as
var newList = new DateTime[Math.Max(date_old.Length, date_new.Length)];
Also make sure the length of date_old equals the length of data_old, same thing for date_new and data_new.
Move newList[c] = data_old[c]; to the outer for loop if you can (i.e. to line 3), it's gonna overwrite your new data assigned to newList.

This exception is thrown when you try to read/write to an array with an index greater than array.Length -1.
Double-check the size of newList.

for (int c = 0; c < date_old.Length; c++)
{
for (int d = 0; d < date_new.Length; d++)
{
newList.Add((date_old[c] == date_new[d] ? data_new[d] : data_old[c]));
}
}
with your list solution and this logic you provided

Related

How can I detect if there are duplicates in a C# array and can I replace them with another suitable value in the same place in the array?

I'm kind of new to C# and I'm trying to make a sudoku game. I'm using a for loop to loop through the column arrays and add a random number to the spots but I'm using Random and Next() so it allows the numbers to repeat. But because I can't have more than one of a number in each column (array) for it to function, how can I replace the repeated number with another number that isn't repeated? I don't know how to do this.
Also the columns are stored in other arrays that I've called rows just so that I can say Row1[0][2] to access position 3 in column 1 for example.
Here's the method & for loop I'm using to replace add the numbers to the arrays:
void populateColumns(int[][] arr) // goes through column arrays and replaces the numbers with random ones from Num()
{
int i;
int j = 0;
for (int l = 0; l <= 8; l++)
{
for (i = 0; i <= 8; i++)
{
arr[j][i] = Num();
int currentPos = arr[j][i];
Console.Write(currentPos);
}
j = l;
}
}

How to compare values in one array?

How can I compare elements in one array?
if the next number in the array is greater than the previous one, then transfer these two values further ... And accordingly, if this is not so, transfer them to another method ...
double[] ipp = { 0.255, 0.232, 0.618, 0.713 };
I'm trying to do so, but the array goes beyond the number of indices
for (int i = 0; i < ipp.Length; i++)
{
if (ipp[i+1] > ipp[i]) // problem
{
// ----> send this
//(ipp[i+1];ipp[i]) values
//to another method
}
}
The problem is in the upper bound check in your for loop. When i = ipp.Length - 1 and you access array item ipp[i + 1] you access an element outside of the array bounds, therefore the problem occurs.
You need to change upper bound check to the i < ipp.Length - 1:
for (int i = 0; i < ipp.Length - 1; i++)
{
if (ipp[i + 1] > ipp[i])
{
...
}
}

Getting the column totals in a 2D array but it always throws FormatException using C#

I am planning to get an array of the averages of each column.
But my app crashes at sum[j] += int.Parse(csvArray[i,j]); due to a FormatException. I have tried using Convert.ToDouble and Double.Parse but it still throws that exception.
The increments in the for loop start at 1 because Row 0 and Column 0 of the CSV array are strings (names and timestamps). For the divisor or total count of the fields that have values per column, I only count the fields that are not BLANK, hence the IF statement. I think I need help at handling the exception.
Below is the my existing for the method of getting the averages.
public void getColumnAverages(string filePath)
{
int col = colCount(filePath);
int row = rowCount(filePath);
string[,] csvArray = csvToArray(filePath);
int[] count = new int[col];
int[] sum = new int[col];
double[] average = new double[col];
for (int i = 1; i < row; i++)
{
for (int j = 1; j < col; j++)
{
if (csvArray[i,j] != " ")
{
sum[j] += int.Parse(csvArray[i,j]);
count[j]++;
}
}
}
for (int i = 0; i < average.Length; i++)
{
average[i] = (sum[i] + 0.0) / count[i];
}
foreach(double d in average)
{
System.Diagnostics.Debug.Write(d);
}
}
}
I have uploaded the CSV file that I use when I test the prototype. It has BLANK values on some columns. Was my existing IF statement unable to handle that case?
There are also entries like this 1.324556-e09due to the number of decimals I think. I guess I have to trim it in the csvToArray(filePath) method or are there other efficient ways? Thanks a million!
So there are a few problems with your code. The main reason for your format exception is that after looking at your CSV file your numbers are surrounded by quotes. Now I can't see from your code exactly how you convert your CSV file to an array but I'm guessing that you don't clear these out - I didn't when I first ran with your CSV and experienced the exact same error.
I then ran into an error because some of the values in your CSV are decimal, so the datatype int can't be used. I'm assuming that you still want the averages of these columns so in my slightly revised verion of your method I change the arrays used to be of type double.
AS #musefan suggested, I have also changed the check for empty places to use the IsNullOrWhiteSpace method.
Finally when you output your results you receive a NaN for the first value in the averages column, this is because when you don't take into account that you never populate the first position of your arrays so as not to process the string values. I'm unsure how you'd best like to correct this behaviour as I'm not sure of the intended purpose - this might be okay - so I've not made any changes to this for the moment, pop a mention in the comments if you want help on how to sort this!
So here is the updated method:
public static void getColumnAverages(string filePath)
{
// Differs from the current implementation, reads a file in as text and
// splits by a defined delim into an array
var filePaths = #"C:\test.csv";
var csvArray = File.ReadLines(filePaths).Select(x => x.Split(',')).ToArray();
// Differs from the current implementation
var col = csvArray[0].Length;
var row = csvArray.Length;
// Update variables to use doubles
double[] count = new double[col];
double[] sum = new double[col];
double[] average = new double[col];
Console.WriteLine("Started");
for (int i = 1; i < row; i++)
{
for (int j = 1; j < col; j++)
{
// Remove the quotes from your array
var current = csvArray[i][j].Replace("\"", "");
// Added the Method IsNullOrWhiteSpace
if (!string.IsNullOrWhiteSpace(current))
{
// Parse as double not int to account for dec. values
sum[j] += double.Parse(current);
count[j]++;
}
}
}
for (int i = 0; i < average.Length; i++)
{
average[i] = (sum[i] + 0.0) / count[i];
}
foreach (double d in average)
{
System.Diagnostics.Debug.Write(d + "\n");
}
}

C# While Loop Unintentional Reference

I am trying to use a while loop to determine when a process is completed, but in order to establish completion, I must compare the previous run with the current run, so I was setting the comparison array to the original... this apparently is creating some sort of reference because when I change a value in the original "Distinct" array, the value also changes in the "InDistinct" comparison array. How can I prevent/work around this? Otherwise my "while(Distinct!=InDistinct)" is useless.
int[,] Distinct = new int[100, 100]; //Establish Distinct Table
int[,] InDistinct= new int[100,100]; //Comparison Array
//Initialize Distinct table to all 0's (not shown)
while (InDistinct != Distinct)
{
InDistinct = Distinct;
for (int j=0; j < DoIt.Sstates.Length; j++)
{
for (; k < DoIt.Sstates.Length; k++)
{
if (DoIt.Sstates[k] == null)
break;
int w = 0;
for (w = 0; w < DoIt.alphabet.Length;w++)
{
if (DoIt.alphabet[w] == '\0')
break;
if (Distinct[j, k] == 0 && Distinct[jim.tLookup(DoIt, j, DoIt.alphabet[w]), jim.tLookup(DoIt, k, DoIt.alphabet[w])] == 1)
Distinct[j, k] = 1;
else if (Distinct[j, k] == 0 && Distinct[jim.tLookup(DoIt, k, DoIt.alphabet[w]), jim.tLookup(DoIt, j, DoIt.alphabet[w])] == 1)
Distinct[j, k] = 1;`
I ended up initiating the InDistinct array above the While loop and copying the Distinct array to it via nested for loops:
int[,] InDistincta= new int[100,100];
while (InDistincta != Distinct)
{
for (int a = 0; a < 100; a++)
{
for (int b = 0; b < 100; b++)
{
InDistincta[a, b] = Distinct[a, b];
}
Isn't this statement at the beginning of your while loop doing this?
while (InDistinct != Distinct)
{
InDistinct = Distinct;
The condition of your loop is checking if the InDistinct array value is not equal to the Distinct value but then makes the two equal by assigning the InDistinct value to that of the Distinct one immediately after.
Arrays are mechanisms that allow you to treat several items as a
single collection. The Microsoft® .NET Common Language Runtime (CLR)
supports single-dimensional arrays, multidimensional arrays, and
jagged arrays (arrays of arrays). All array types are implicitly
derived from System.Array, which itself is derived from System.Object.
This means that all arrays are always reference types which are
allocated on the managed heap, and your app's variable contains a
reference to the array and not the array itself.
https://msdn.microsoft.com/en-us/library/bb985948.aspx
So you need to change
InDistinct = Distinct;
just because after that line, the two names refers the same object.
try to copy target array into to the InDistinct object
targetArray = new string[sourceArray.Length];
sourceArray.CopyTo( targetArray, 0 );
for multi-dimensional arrays
Array.Copy(sourceArray,targetArray, sourceArray.Length);

trying to int.parse multi array string

Im doing this:
string[,] string1 = {{"one", "0"},{"Two", "5"},{"Three","1"}};
int b = 0;
for(int i = 0; i <= string1.Length; i++)
{
b = int.Parse(string1[i, 1]); // Error occurs here
}
Im getting an error saying that "index extent the limits of the array" (or something like that, the error is in danish).
There are two problems:
string1.Length will return 6, as that's the total length of the array
You're using <= for the comparison, so it would actually try to iterate 7 times.
Your for loop should be:
for (int i = 0; i < string1.GetLength(0); i++)
The call to GetLength(0) here will return 3, as the size of the "first" dimension. A call to GetLength(1) return 2, as the second dimension is of size 2. (You don't need that though, as you're basically hard-coding the knowledge that you want the second "column" of each "row".)
See the docs for Array.GetLength() for more details.
Your array bounds are incorrect in the loop:
for(int i = 0; i <= string1.Length; i++)
should read:
for(int i = 0; i < string1.GetLength(0); i++)
Two things were wrong: <= versus < meant you were going one item too far, and .Length returns the total length of the array (6) versus GetLength(0) which returns the length of the first dimension (3).
You already have the right answer, I'll update mine just to correct it. To right iteration should be
for (int i = 0; i < string1.GetLength(0); i++)
{
b = int.Parse(string1[i, 1]);
}
Because i stands for the length of the first dimension, and the fixed 1 will return the number, that is the second element.
I'm sorry for the wrong answer I gave first.
Change i <= string1.Length to i < string1.Length.
change to
for(int i = 0; i <= string1.GetLength(0); i++)
{
b = Int32.Parse(string1[i][0]);
}
Your code is refering at index 1 rather than 0 which causes exception known as Array out of bound
Try this:
for(int i = 0; i < string1.GetLength(0) ; i++)
{
b = int.parse(string1[i, 0]); // Error occurs here
}
Array.GetLength Method
Gets a 32-bit integer that represents the number of elements in the specified dimension of the Array.
Also worth mentioning that int.Parse may throw a FormatException, consider int.TryParse.

Categories