populate Jagged Array with files C# - c#

I can't seem to figure out how to work with Jagged Arrays and Files. I have three files with numbers in them and wan to read each file into its own array. This is what I have so far. Was trying to populate the [0] array but to no avail. Any help appreciated. Can't find any tutorials on doing this, either.
private void button1_Click(object sender, EventArgs e)
{
StreamWriter section1;
StreamWriter section2;
StreamWriter section3;
StreamReader section1read;
StreamReader section2read;
StreamReader section3read;
section1 = File.CreateText("Section1.txt");
section2 = File.CreateText("Section2.txt");
section3 = File.CreateText("Section3.txt");
int[][] Scores = new int[3][];
Random randnum = new Random();
for (int i = 0; i < 12; ++i)
{
int num = randnum.Next(55, 99);
section1.WriteLine(num);
}
for (int j = 0; j < 8; ++j)
{
int num1 = randnum.Next(55, 99);
section2.WriteLine(num1);
}
for (int k = 0; k < 10; ++k)
{
int num3 = randnum.Next(55, 99);
section3.WriteLine(num3);
}
section1.Close();
section2.Close();
section3.Close();
section1read = File.OpenText("Section1.txt");
int nums = 0;
while (!section1read.EndOfStream)
{
Scores[0][nums] = int.Parse(section1read.ReadLine());
++nums;
}
for (int i = 0; i < Scores.Length; ++i)
{
listBox1.Items.Add(Scores[0][i]);
}
section1read.Close();
}

Jagged arrays should be initialized in two steps:
The array itself:
int[][] Scores = new int[3][];
The sub-arrays:
Scores[0] = new int[12];
Scores[1] = new int[8];
Scores[2] = new int[10];
Array is a fixed length data structure. If you don't know the size in advance, you have to use a dynamic length structure. The best option is List<> class:
List<List<int>> scores = new List<List<int>>();
scores.Add( new List<int>() );
using( StreamReader section1read = File.OpenText("Section1.txt"))
{
string line;
while ((line = section1read.ReadLine()) != null)
{
scores[0].Add(int.Parse(line));
}
}
Here are other things to consider:
Use a using block make sure any unmanaged resources associated with file is disposes.
You can check the return value of StreamReader.ReadLine() to determine the end of file

http://msdn.microsoft.com/en-us/library/2s05feca.aspx
Quote:
"Before you can use jaggedArray, its elements must be initialized. You can initialize the elements like this:
jaggedArray[0] = new int[5];
jaggedArray[1] = new int[4];
jaggedArray[2] = new int[2];"
So, what you're doing in your code is initializing a jagged array of three int[]s that are all set to null. If you don't create the array at each index before attempting to assign to it, nothing is there.
It seems what you want, though, is dynamic allocation - you don't know how many integers you need to store when you wrote the program. In this case, you should learn about the class List<>. List<> is like an array except you can add to and remove from the number of elements it has at runtime, rather than declaring it has a fixed size, using Add and Remove. http://msdn.microsoft.com/en-us/library/6sh2ey19.aspx

Related

Is there any way to not have to specify an array size before modifying its elements?

Let's say I want to write a value in a int[], but I don't yet know what will be the length of that array.
Currently, I just run whatever algorithm I'm using once to get the length of the array, then I instanciate the array and finally run the same algorithm modifying the elements of the array.
Here's a code example:
for (int i = 0; i < input.length; i++)
{
if (i == condition)
{
length++;
}
}
array = new int[length];
for (int i = 0; i < input.length; i++)
{
if (i == condition)
{
array[i] = whatever;
}
}
Just use lists
List<string> list = new List<string>();
When adding elements just do:
list.Add("Hello, world!");
You do not need to specify length for a list and you can add as many elements as you like
https://www.c-sharpcorner.com/article/c-sharp-list/
https://learn.microsoft.com/en-us/dotnet/api/system.collections.generic.list-1?view=net-6.0

New Blank 2D array without size

I need to create an array for which I do not know the size in advance. I used the following, but it gives an index out of bounds error in my for -loop.
string[] arr = s.Split('\n');
int[] indices = new int[arr.Length];
string[][] new_arr = new string[arr.Length][];
for (int i = 0; i < arr.Length; i++)
{
if (arr[i].StartsWith("21"))
{
indices[i] = i;
}
}
indices = indices.Where(val => val != 0).ToArray(); //contains indices of records beginning with 21
for (int i = 0; i < indices.Length - 1; i++)
{
new_arr[0][i] = arr[i];
} //first n elements
The error is in the second for-loop. It says
Object reference not set to an instance of an object.
But I did instantiate the string at the beginning?
You just need to initialize each of the arrays within the jagged array:
indices = indices.Where(val => val != 0).ToArray(); //contains indices of records beginning with 21
// create second-level array
new_arr[0] = new string[indices.Length] ;
for (int i = 0; i < indices.Length - 1; i++)
{
new_arr[0][i] = arr[i]; // why 0 here?
}
For a 2 dimensional array, you will have to specify the size of the first dimension. As I see your code, it is using what is called the jagged array (array containing array as elements) and not a pure 2 dimensional array.
var array1 = new int[2,10]; // this is a 2 dimensional array
var array2 = new int[2][]; // this is an array of 2 elements where each element is an `int[]`
As you notice, we don't need to specify the size of the inside element int[]
Now you understand the jagged array, you can see that you are not initializing the inside element, but simply accessing it - and since it is null by default, you hit the exception.
for (int i = 0; i < indices.Length - 1; i++)
{
new_arr[0][i] = arr[i];
} //first n elements
In the code above, you should have new_arr[i][0] = arr[i] and also before that line you need to do new_arr[i] = new int[x] where x is teh size that you want for the inside array.

How can I initialize a 2-d C# array to all of the same value?

What I want to do is described in the comment below. How can I do, efficiently?
using System;
using System.Collections.Generic;
using System.IO;
class Solution {
static void Main(String[] args) {
int n = Int32.Parse(Console.ReadLine());
bool[][] flags = new bool[26][n]; // I want this to be a 26 x n array of false values
for(int k = 0; k < n; ++k)
{
string line = Console.WriteLine();
for(int i = 0; i < line.Length; ++i)
flags[(int)line[i] - (int)'a'] = true;
}
int gems = flags.Count(arr => arr.Count(j => j == true) == arr.Length);
Console.WriteLine
}
}
LINQ should work well for your goal:
bool[][] flags = Enumerable.Range(0, 26).Select(_ => Enumerable.Repeat(true, n).ToArray()).ToArray();
Or as Jim Mischel said:
bool[][] flags = Enumerable.Repeat(Enumerable.Repeat(true, n).ToArray(), 26).ToArray();
But the first example uses less memory becuase the Select method doesn't re-define Enumerable.Repeat(true, n).ToArray() as it goes through the items.
Looks like you are confused between Multidimensional arrays and Jagged Array (Array of Arrays).
If you are looking for 2d Array, you could simply do this.
bool[,] flags = new bool[26,n];
//or
bool[,] flags = new bool[,];
bool[,] flags = new bool[26,];
If it is Jagged Arrays, you could do this.
bool[][] flags1 = new bool[26][];
flags1[0] = new bool[n]; // since you want n elements
flags1[1] = new bool[n];
...
// initialization
flags1[0] = new bool[] {true, false};
flags1[1] = new bool[] {false};

C# Multi-dimensional Array

I'm trying to build a multi-dimensional array to store integer arrays.
Array[] TestArray = new Array[2];
for(int i = 0; i < TestArray.Length; i++)
{
TestArray[i] = new int[5];
}
How do I go about accessing the newly created members of the Array? I am not sure how to access the newly created arrays in the array although I can see that they're properly created and stored when debugging in Visual Studio.
If you want an array of integer arrays, then you should declare it as such:
int[][] testArray = new int[2][];
for(int i = 0; i < testArray.Length; i++)
{
testArray[i] = new int[5];
}
Arrays of arrays are called Jagged Arrays (in contrast to Multidimensional Arrays).
Here is how to access fourth item in the second array:
int value = ((int[]) TestArray.GetValue(1))[3];
Although you would have much less trouble working with jagged arrays:
int[][] TestArray = new int[2][];
for (int i = 0; i < TestArray.Length; i++)
{
TestArray[i] = new int[5];
}
or multidimensional arrays:
int[,] TestArray = new int[2,5];
Cast the TestArray element as an int[].
Array[] TestArray = new Array[2];
for(int i = 0; i < TestArray.Length; i++)
{
TestArray[i] = new [] { 2,3 };
}
var firstIndexOfFirstArray = ((int[])TestArray[0])[0];
T[][] is the syntax you are looking for.
int[][] test = new int[2][]; //Declaring the array of arrays.
for (int i = 0; i < test.Length; i++)
{
test[i] = new int[5]; //Instantiating a sub-arrays.
for (int x = 0; x < test[i].Length; x++)
test[i][x] = x + i; //Filling a sub-arrays.
}
foreach (var array in test) //iterating over the array of arrays.
Console.WriteLine("Array: " + string.Join(", ", array)); //using a sub-array
Console.ReadLine();
For more info: http://msdn.microsoft.com/en-us/library/2s05feca.aspx
If looking for integer array, try
int[][] testArray

2-dimensional array assignment: "reference to an object was not set for an instance of the object"

I'm getting "reference to an object was not set for an instance of the object" run-time error with the suggestion: "Use the new keyword to create an object instance.
But I don't understand what I'm doing wrong.
There is my code:
int numListas = 10;
x = 15;
int[][] listas;
listas = new int[numListas][];
Random random = new Random(); // generate random number
for (idx = 0; idx < numListas; idx++)
{
int idx_el;
for (idx_el = 0; idx_el < x ; idx_el++)
{
listas[idx][idx_el] = random.Next(0,100);
}
}
This line:
int[][] listas;
declares a variable which is a reference to an array of arrays.
This line:
listas = new int[numListas][];
initializes the variable to refer to an array of numListas array references... but each of those "subarray" references is null to start with. You need to initialize each "subarray", probably in your outer loop:
for (idx = 0; idx < numListas; idx++)
{
listas[idx] = new int[x];
...
}
Note that an alternative is to use a rectangular array instead of an array of arrays:
int[,] listas = new int[numListas, x];
...
// In your loop
listas[idx, idx_el] = random.Next(0, 100);
As an aside, code generally reads more clearly when you declare and initialize variables together, rather than declaring them earlier and then initializing them later. Also, underscores in C# variable names aren't terribly idiomatic, and the overall variable names aren't terribly clear. I'd write your code as:
// Consider declaring these as constants outside the method
int rowCount = 10;
int columnCount = 15;
int[][] values = new int[rowCount];
Random random = new Random();
for (int row = 0; row < rowCount; row++)
{
values[row] = new int[columnCount];
for (int column = 0; column < columnCount; column++)
{
values[row][column] = random.Next(100);
}
}
You should also consider initializing a single Random instance outside the method and passing it in - see my article on Random for more information.
You need to initialize each inner array within your jagged array:
int numListas = 10;
x = 15;
int[][] listas;
listas = new int[numListas][];
Random random = new Random(); // generate random number
for (idx = 0; idx < numListas; idx++)
{
listas[idx] = new int[x]; // initialize inner array
int idx_el;
for (idx_el = 0; idx_el < x ; idx_el++)
{
listas[idx][idx_el] = random.Next(0,100);
}
}
Alternatively, you may use a two-dimensional array:
int numListas = 10;
x = 15;
int[,] listas;
listas = new int[numListas,x]; // 2D array
Random random = new Random(); // generate random number
for (idx = 0; idx < numListas; idx++)
{
int idx_el;
for (idx_el = 0; idx_el < x ; idx_el++)
{
listas[idx,idx_el] = random.Next(0,100);
}
}
You don't set a dimension for the second dimension
listas = new int[numListas][];.
As you are using x as the limit of your loop, use that as dimension:
for (idx = 0; idx < numListas; idx++)
{
int idx_el;
listas[idx] = new int[x]; // initialize the second dimension
for (idx_el = 0; idx_el < x ; idx_el++)
{
listas[idx][idx_el] = random.Next(0,100);
}
}
Alternatively, you can use a rectangular array at the beginning:
int[,] listas = new int[numListas,x];
Did you forget to initialize the second dimension of the array?
listas = new int[numListas][x];
initialize this ^

Categories

Resources