How to create mutlidimensional list for this in C#? - c#

I got a table (in file) which I split into blocks by spaces.
I need structure like this:
-----------------------------
|21|22|23|33|3323|
|32|32|
|434433|545454|5454|
------------------------------
It's more like each row is its own table. How should I do this?
I tried List<List<string>> matrix = new List<List<string>>(); but I can't seem to find a way to work with it.
EDIT - can someone tell me what's wrong with this code???? Matrix[0][0] is same as matrix [1][0].. it seems that same row is added to matrix all the time, but I clear it ...
static ArrayList ReadFromFile(string filename)
StreamReader SR;
string S;
string[] S_split;
SR = File.OpenText(filename);
S = SR.ReadLine();
ArrayList myItems = new ArrayList();
List<List<string>> matrix = new List<List<string>>();
List<string> row = new List<string>();
while (S != null)
{
row.Clear();
S_split = S.Split(' ');
for (int i = 1; i < S_split.GetLength(0); i++)
{
row.Add(S_split[i]);
matrix.Add(row);
}
S = SR.ReadLine();
}
Console.WriteLine(matrix[1][1]);
SR.Close();
return myItems;
}

Not sure if I understand this correctly.
List<List<int>> table = new List<List<int>>();
List<int> row = new List<int>();
row.Add(21);
row.Add(22);
row.Add(23);
row.Add(33); // and so on
table.Add(row);
row = new List<int>();
row.Add(1001);
row.Add(1002);
table.Add(row);
MessageBox.Show(table[0][3].ToString());
The program should show a message box with text "33".

You should be able to work with it as you'd expect to deal with a list within a list.
matrix.Add(new List<string>);
matrix[0].Add("a string");

List<List<String>> matrix = new List<List<String>>();
foreach (String line in file)
{
String[] values = line.Split(new Char[] { ' ' });
matrix.Add(new List<String>(values));
}
Just iterate through your file and for every line do the following.
Generate a new List
Fill it with the data for the line
Add the list for the current line to your list for the complete file
Note that foreach (String line in file) is just pseudo code. Further you can merge the to lines in the body to a single line.
matrix.Add(new List<String>(line.Split(new Char[] { ' ' })));

You're describing a jagged array. I'm not exactly sure if a List won't be overkill? If you just have to import the data from the file and than use it, a jagged array should be simple enough.
Example:
int[][] jaggedArray = new int[][]
{
new int[] {21, 22, 23, 33, 3323},
new int[] {32, 32},
new int[] {434433, 545454, 5454}
};
you can also buildup the jagged array in a loop while processing your file, like this:
int[][] result = new int[numberOfLines][];
for (int currentLine = 0; currentLine < numberOfLines; currentLine++)
{
String line = fileStream.ReadLine();
int[] values = SplitAndConvertLine(line);
result[currentLine] = values;
}

If you are trying to read from the file then try something like the following (Note the following code has not been run through a compiler)
List<string[]> matrix = new List<string[]>();
while(!instream.EndOfStream)
{
var values = instream.ReadLine().Split(new[] {' '});
matrix.Add(values);
}

Related

How to implement string[] into string[] in C#?

I want to implement 'string[] loadedText' into 'string[] dataList', but I keep getting an error saying "Cannot implicitly convert type 'string[]' to 'string'".
string[] dataList = new string[1800];
StreamReader loadNewData = new StreamReader("podaciB.txt");
int i = 0;
while (i < 1800)
{
string[] loadedData = loadNewData.ReadLine().Split(';');
dataList[i] = loadedData;
i++;
}
I need the 'dataList' array that will contain 1800 'loadedData' arrays which contain 4 strings in them.
What you need is a jagged array:
string[][] dataList = new string[1800][];
loadNewData.ReadLine().Split(';'); returns array of string and you are storing array of strings into dataList[i] i.e. string element of string array. This is the reason behind error which you mentioned in your question
If you want to store loadNewData.ReadLine().Split(';'); into an array then I would suggest you to use nested list List<List<string>>
Something like,
List<List<string>> dataList = List<List<string>>();
StreamReader loadNewData = new StreamReader("podaciB.txt");
int i = 0;
while (i < 1800)
{
var innerList = loadNewData.ReadLine().Split(';').ToList();
dataList.Add(innerList);
i++;
}
It seems you need an array of array of strings, something like string[][].
You can do it like this:
string[][] dataList = new string[1800][];
StreamReader loadNewData = new StreamReader("podaciB.txt");
int i = 0;
while (i < 1800)
{
string[] loadedData = loadNewData.ReadLine().Split(';');
dataList[i] = loadedData;
i++;
}
As you are splitting loadedNewData, you receive string[] already, because Split() function returns string[].

Making a mulitdimensional jagged array

I want to make a dynamic array of dynamic arrays, how can I do that?
I've tried with list of list where I use the AddRange() method.
I've also tried iterating through arrays.
Maybe it makes more sense to show what I'm trying to do. I cannot get it to work:
String[] lines = System.IO.File.ReadAllLines(fileName);
String[] linesArr;
String[][] MultiArr;
int i = 0;
foreach (string line in lines)
{
if (line.Contains("EFIX"))
{
linesArr = line.Split(delimiterChars);
for (int x = 0; x < linesArr.Length; x++)
{
MultiArr[i][x] = linesArr[x];
}
Console.WriteLine(fixationsData[i]);
i++;
}
}
LINQ makes this pretty trivial.
string[][] data = File.ReadLines(filename)
.Where(line => line.Contains("EFIX"))
.Select(line => line.Split(delimiterChars))
.ToArray();//omit this last call to allow the data to be streamed,
//greatly removing the memory footprint of the application at no real
//additional cost, assuming you have no compelling reason to eagerly
//load the whole file into memory.
foreach(var line in data)
Console.WriteLine(line);
Using a list of list of strings should work fine. Here's what I'd write.
var lines = System.IO.File.ReadAllLines(fileName);
var multiArr = new List<List<string>>();
var i = 0;
foreach (var line in lines.Where(line => line.Contains("EFIX")))
{
multiArr.Add(line.Split(delimiterChars).ToList());
Console.WriteLine(fixationsData[i]);
i++;
}
String[] lines = System.IO.File.ReadAllLines(fileName);
String[] linesArr;
List<String[]> MultiArr = new List<String[]>();
foreach (string line in lines)
{
if (line.Contains("EFIX"))
{
linesArr = line.Split(delimiterChars);
MultiArr.Add(linesArr);
Console.WriteLine(fixationsData[i]);
}
}
This is a list of string arrays. This is what you are looking for.

Get multidimensional array from text files

I have static class theat declare the array:
static class GlobalDataClass
{
public static double[,] dDataArray = new double[10, 2];
}
Now I have a function that stream the text file line by line by having the number of rows and index of the array:
using (StreamReader sr = new StreamReader(filename))
{
double[] dx = new double[lines]; //lines store number of rows
double[] dy = new double[lines]; //lines store number of rows
for (long li = 0; li < lines; li++)
{
dx[li] = GlobalDataClass.dDataArray[li, 0];
dy[li] = GlobalDataClass.dDataArray[li, 1];
}
}
My text file will be like:
1,2
2,3
3,4
5,6
Now how to have the output matrix like:
dx[1] [0,0] = 1
dy[1] [0,1] = 2
and so on.
For create multidimensional array, you can use list of list:
List<List<string>> ls = new List<List<string>>();
var filename="aa.txt";
StreamReader sr = new StreamReader(filename);
while (!sr.EndOfStream)
{
var line = sr.ReadLine();
var element = line.Split(',');
List<string> temp = new List<string>();
foreach (var item in element)
{
temp.Add(item);
}
ls.Add(temp);
}
In this code, every line may have many element (>2).
you can read the file and split each line at the comma, like this:
StreamReader sr = new StreamReader("MyNumbers.txt");
String line;
String[] lineSeperate;
line = sr.ReadLine();
lineSeperate = line.Split(',');
now, dx[index] = lineSeperate[0] and dy[index]=lineSeperate[1]
Edit
You need to convert from String to double:
dx[0] = double.Parse(lineSeperate[0]);
dy[0] = double.Parse(lineSeperate[1]);

C# How do I parse a text file of data of unknown row size to a 2D array?

I can easily pass a data file to a 2D array if I know the size of the data file, but thats pretty pointless when you want to add and remove data.
How can I instantiate a 2D array of that Data rows length that is global and not out of scope to the rest of the program?
Here is the usual code, for an array of 4 rows and 6 columns, but I want to add/remove data to the data file making it of unknown length in rows.
string[,] allStudentData = new string[4, 6];
string[] allStudents = File.ReadAllLines("data.txt");
for (int i = 0; i < allStudents.Count(); i++)
{
for (int j = 0; j < 6; j++)
{
string[] DataIn = allStudents[i].Split(',');
allStudentData[i, j] = DataIn[j];
}
}
Thanks for your ideas :-)
Why not use something mutable, like a List ?
You can add columns using the .Add() command, , and you can collapse it into an array when you're done with it (.ToArray())
you can do as below
var result = File.ReadAllLines("data.txt").Select(x=>x.Split(',')).ToArray();
You can use a List that holds a custom object (it could be an array) instead of Array and then at the end convert the list to an array with the ToArray extension:
var list = new List<string[]>();
var data1 = new string[2] {"1", "2" };
var data2 = new string[3] {"1", "2", "3" };
list.Add(data1);
list.Add(data2);
list.ToArray(); // converts the list to string[][]
After you are done reading the file you could add easily more items to the list and then at the end write all modifications to the file. If you think, that in future you will need more than the two dimensional array, than it's worth it to create a custom object like:
public class Student
{
public string Name { get; set; }
public int Grade { get; set; }
}
and use this instead of the string[]:
var studentData = new List<Student>();
The maintenance later will be much more easier (adding address, classes, and so on). I admit, you will have a little more work to do when reading and writing, but if the project grows it will pay off.
You can still use LINQ to read the data on one line:
// creates a List<Student>
var studentData = File.ReadAllLines("data.txt")
.Select(row => row.Split(','))
.Select(elements =>
new Student
{
Name = elements[0],
Grade = int.Parse(elements[1])
}).ToList();
If the number of columns is always 6 and only the number of rows is unknown. Just change the first 2 rows of your code to:
string[] allStudents = File.ReadAllLines("data.txt");
string[,] allStudentData = new string[allStudents.Count(), 6];
If the number of columns is unknown you can do this to get a 2D result:
var not2DResult = File.ReadAllLines("data.txt").Select(x => x.Split(',')).ToArray();
var maxRow = not2DResult.Count()-1;
int maxColumn = Enumerable.Select(not2DResult, c => c.Count()).Max()-1;
var result2D = new string[maxRow, maxColumn];
for (int rowNumber = 0; rowNumber < maxRow; rowNumber++)
{
var row = not2DResult[rowNumber];
for (int columnNumber = 0; columnNumber < row.Count(); columnNumber++)
{
result2D[rowNumber, columnNumber] = row[columnNumber];
}
}
Try using a Lists to hold the file information.
var myList = new List<string>();
myList = File.ReadLines("data.txt");
var my2DList = new List<List<string>>();
foreach(string line in myList)
my2DList.Add(line.Split(','));
If you want to know the number of lines, just use:
int numberOfLines = my2DList.Count;
For the number of items in an individual line:
int lengthOfLine3 = my2DList[3].Length;

I need to initialize a 2D array by reading lines from a .txt file then splitting each individual line every time a semicolon shows up in each line

Here is my problem:
I have a program (using the console) that prompts users for data as such:
Name:
Date:
Birthday:
The user enters the data, then the data is recorded in a .txt file, each line being one instance the user entered data, with each individual piece of data being separated by a semicolon. The text file looks like this:
John Smith;7/14/2015;6/5/1980
Jane Doe;7/15/2015;3/4/1975
What I want to do is take each line of text, split it by semicolon, and put all of that text in one 2D array. Here is the code I have so far:
public static void lineSplitCreator()
{
string[, ] portionsOfAllData; //the 2D array
string[] linesOfPatientData = System.IO.File.ReadAllLines(#"C:\Users\Administrator.Rahul-HP\Desktop\test\dataOfPatient.txt");
//read all lines and put them into this array
foreach (string s in linesOfPatientData) //attempt at initializing the 2D array
{
for (int i = 0; i < 5; i++)
{
portionsOfAllData[i, ] = s.Split(';');
}
}
}
How do I do this?
Because I'm not sure how many elements the Split() could produce, I suggest using a jagged array.
A jagged array is declared like:
string[][] myJaggedArray;
For your code, make the following changes and you should be good to go.
public static void lineSplitCreator()
{
string[] linesOfPatientData = System.IO.File.ReadAllLines(#"C:\Users\Administrator.Rahul-HP\Desktop\test\dataOfPatient.txt");
// This is your jagged array. We know how many rows will have from linesOfPatientData
string[][] portionsOfAllData = new string[linesOfPatientData.Length][]; // The 2D array
// Read all lines and put them into this array
for (int i = 0; i < linesOfPatientData.Length; i++)
{
portionsOfAllData[i] = linesOfPatientData[i].Split(';');
}
}
Or use a List<string[]>
public static void lineSplitCreator()
{
string[] linesOfPatientData = System.IO.File.ReadAllLines(#"C:\Users\Administrator.Rahul-HP\Desktop\test\dataOfPatient.txt");
List<string[]> portionsOfAllData = new List<string[]>();
// Read all lines and put them into this array
foreach (string s in linesOfPatientData)
{
portionsOfAllData.Add(s.Split(';'));
}
}
If you truly want a 2D array, you need to know exactly how many elements are in a line... as mentioned in another answer, a jagged array might be a better fit, but, this is how you can do it with a 2D array:
var testString = #"John Smith;7/14/2015;6/5/1980
Jane Doe;7/15/2015;3/4/1975";
var arr = testString.Split(new[] {'\r', '\n'}, StringSplitOptions.RemoveEmptyEntries);
var output = new string[arr.Length, 3];
for(var rowNumber = 0; rowNumber < arr.Length; rowNumber++)
{
var line = arr[rowNumber];
var lineItems = line.Split(';');
for(var columnNumber=0; columnNumber < 3; columnNumber++)
{
output[rowNumber,columnNumber] = lineItems[columnNumber];
}
}

Categories

Resources