Get multidimensional array from text files - c#

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]);

Related

want to move each array from arrayList into int [ ]

there are 350 elements in my arraylist , each of it consist of an array of 9 integers i-e Count of each element is 9 . i want to retrievere each of it.
here is what i am trying but giving me
error
"Unable to cast object of type
'System.Collections.Generic.List`1[System.Int32]' to type
'System.Int32[]'."
FileName = "E:\\Normalized_sheet1.txt";
FileStream Fs = File.OpenRead(FileName);
StreamReader SR = new StreamReader(Fs);
while (!SR.EndOfStream)
{
Line = SR.ReadLine().Split('\t'); //make an array of text each time
List<string> arr = new List<string>();
arr.AddRange(Line);
List<int> intList = arr.ConvertAll(s => Int32.Parse(s));
myvalues.Add(intList);
}
SR.Close();
Fs.Close();
for (i = 0; i < Samples; i++)
{
InputParameter=(int[]) myvalues[i]; // Error
}
myvalues.Add(intList.ToArray());
Because you mentioned that you have a list of arrays. If it's a List<int[]> then you can't add lists to it - you can only add arrays. ToArray() returns an array of the items in your list.
If "myvalues" is a List of int[] then your loop should look like this:
for (i = 0; i < Samples; i++)
{
InputParameter= myvalues[i]; //don't need cast.
}
if myvalues is a List of List of int, then your code should be:
for (i = 0; i < Samples; i++)
{
InputParameter= myvalues[i].ToArray();
}
Do not cast, use the appropriate List method:
InputParameter=myvalues[i].ToArray();

Troubles with reading text file after Build

I'm having trouble reading a text file in Unity3D.
I've created a method which returns a type float[][] and takes a streamreader as argument:
public float[][] CreateWeights(StreamReader reader){
int n = 0;
float[][] Weights = new float[50][];
while((!reader.EndOfStream)){
string text = reader.ReadLine();
if (text == null)
break;
string[] strFloats = text.Split (new char[0]);
float[] floats = new float[strFloats.Length];
for(int i = 0; i<strFloats.Length; i++){
floats[i] = float.Parse(strFloats[i]);
}
Weights[n] = floats;
n++;
}
return Weights;
}
I make use of this method in void Start() to create "weights":
float[][] WeightsIH;
float[][] WeightsHO;
void Start(){
FileInfo theSourceFile = new FileInfo(Application.dataPath + "/Resources/WeightsIH.txt");
StreamReader reader = theSourceFile.OpenText();
FileInfo theSourceFile2 = new FileInfo(Application.dataPath + "/Resources/WeightsHO.txt");
StreamReader reader2 = theSourceFile2.OpenText();
WeightsIH = CreateWeights(reader);
WeightsHO = CreateWeights(reader2);
Yhidden = new float[50][];
HiddenOutput = new float[50][];
Xoutput = new float[1];
}
And this will work fine in Unity's play mode. However, after creating an executable, the files won't be found, which I do understand. So to make it work, I understood that I need to use Resources.Load and I have:
void Start(){
TextAsset text1 = Resources.Load("WeightsIH") as TextAsset;
TextAsset text2 = Resources.Load("WeightsHO") as TextAsset;
WeightsIH = CreateWeights(text1);
WeightsHO = CreateWeights(text2);
Yhidden = new float[50][];
HiddenOutput = new float[50][];
Xoutput = new float[1];
}
Of course the argument type can't be a streamReader anymore, and I changed it to take TextAsset as argument. Here's how it changed:
public float[][] CreateWeights(TextAsset textAsset){
float[][] Weights = new float[50][];
string[] linesFromFile = textAsset.text.Split("\n"[0]);
for(int i = 0; i<linesFromFile.Length; i++){
string[] strFloats = linesFromFile[i].Split (new char[0]);
float[] floats = new float[strFloats.Length];
for(int j = 0; j<strFloats.Length; j++){
floats[j] = float.Parse(strFloats[j]);
}
Weights[i] = floats;
}
return Weights;
}
Now this won't work at all, not even in play mode. The run-time error I would get is as follows:
FormatException: Invalid format.
System.Double.Parse (System.String s, NumberStyles style,
IFormatProvider provider) ( at
/Users/builduser/buildslave/mono-runtime-and-classlibs/build/mcs/class/corlib/System/Double.cs:209)
System.Single.Parse (System.String s) ( at
/Users/builduser/buildslave/mono-runtime-and-classlibs/build/mcs/class/corlib/System/Single.cs:183)
FollowShortestPath.CreateWeights (UnityEngine.TextAsset textAsset)
( at Assets/Scripts/Pathfinding/FollowShortestPath.cs:203)
FollowShortestPath.Start () ( at
Assets/Scripts/Pathfinding/FollowShortestPath.cs:54)
line 54 refers to:
WeightsIH = CreateWeights(text1);
and line 203 refers to:
floats[j] = float.Parse(strFloats[j]);
What am I doing wrong? How can I get the text files to be read successfully in in the executable?
The problem you have is with text file format you are loading.
Couse you have many white spaces
string[] strFloats = text.Split (new char[0]);
will result in that some strings are empty.
To fix this, remove extra withe spaces from text files or use:
for(int j = 0; j<strFloats.Length; j++){
if (string.IsNullOrEmpty (strFloats [j]))
continue;
floats[j] = float.Parse(strFloats[j]);
}

Copy 2D Array in C#

I have a code that stored the data to a temporary array.
string filename = openFileDialog1.FileName;
string[] line = File.ReadAllLines(filename);
using (var reader2 = File.OpenText(#filename))
{
for (int i = 0; i < line.Length; i++)
{
string lines = reader2.ReadLine();
var data = lines.Split(',');
double[,] arrayTemp = new double[line.Length, 2];
arrayTemp[i, 0] = double.Parse(data[0]);
arrayTemp[i, 1] = double.Parse(data[1]);
}
Array.Copy(arrayTemp, GlobalDataClass.dDataArray, line.Length); //error the name "arrayTemp" does not exist in the current context.
}
Since 2d array is not resizable and I want my global array to be flexible,so I use the Array.Copy method to copy the temp array to the Global class array. However I got an error as commented in my code above.
My question is how to copy the tempArray to the global class array.
Any idea how to fix this?
Problem : You have declared your array variable arrayTemp inside the for loop and it is not available outside of it.
Solution : You need to move your array variable arrayTemp declaration outside the loop.
Try This:
string filename = openFileDialog1.FileName;
string[] line = File.ReadAllLines(filename);
double arrayTemp=new double[line.Length,2];//declare outside forloop so it available after forloop.
GlobalDataClass.dDataArray=new double[line.Length,2]; //add this line
using (var reader2 = File.OpenText(#filename))
{
for (int i = 0; i < line.Length; i++)
{
string lines = reader2.ReadLine();
var data = lines.Split(',');
GlobalDataClass.dDataArray[i, 0] = double.Parse(data[0]);
GlobalDataClass.dDataArray[i, 1] = double.Parse(data[1]);
}
Array.Copy(arrayTemp, GlobalDataClass.dDataArray, line.Length);
}
EDIT:
it seems that you are trying to copy the contents of arrayTemp to GlobalDataClass.dDataArray, but you are assigning values to GlobalDataClass.dDataArray, and trying to copy empty arrayTemp to GlobalDataClass.dDataArray.
So first declare the tempArray outside the for-loop and then populate it instead of GlobalDataClass.dDataArray inside the for-loop accordingly:
string filename = openFileDialog1.FileName;
string[] line = File.ReadAllLines(filename);
var arrayTemp = new double[line.Length, 2];
using (var reader2 = File.OpenText(#filename))
{
for (int i = 0; i < line.Length; i++)
{
string lines = reader2.ReadLine();
var data = lines.Split(',');
arrayTemp[i, 0] = double.Parse(data[0]);
arrayTemp[i, 1] = double.Parse(data[1]);
}
Array.Copy(arrayTemp, GlobalDataClass.dDataArray, line.Length); // now the error should go away.
}
EDIT 2:
you don't need to read the file 2nd time in the using() clause.
Now please try the following:
string filename = openFileDialog1.FileName;
string[] line = File.ReadAllLines(filename);
var arrayTemp = new double[line.Length, 2];
for (int i = 0; i < line.Length; i++)
{
var data = line[i].Split(',');
arrayTemp[i, 0] = double.Parse(data[0]);
arrayTemp[i, 1] = double.Parse(data[1]);
}
Array.Copy(arrayTemp, GlobalDataClass.dDataArray, line.Length); // now the error should go away.
Your tempArray is out of the scope of you Array.Copy because it is inside of your for loop, you need to move it into the scope of your method call so the method can access it. (Similar to how GlobalDataClass.dDataArray is declared elsewhere)
//Array is now declared in an accessible scop
double[,] arrayTemp;
string filename = openFileDialog1.FileName;
string[] line = File.ReadAllLines(filename);
using (var reader2 = File.OpenText(#filename))
{
for (int i = 0; i < line.Length; i++)
{
string lines = reader2.ReadLine();
arrayTemp = new double[line.Length, 2];
var data = lines.Split(',');
GlobalDataClass.dDataArray[i, 0] = double.Parse(data[0]);
GlobalDataClass.dDataArray[i, 1] = double.Parse(data[1]);
}
Array.Copy(arrayTemp, GlobalDataClass.dDataArray, line.Length); //error the name "arrayTemp" does not exist in the current context.
}
Statements "deeper" into the { } hierarchy are only accessible to statements within them, and other child scopes in them. Parent scopes outside of the original brackets cannot access the variables.
looks like you array is out of scope because it's declared inside the for loop and you are trying to access it outside the for loop
I have answered on this link
To copy an array to another one, just use the "Clone()" function like the following:
This is your array list
object newArray = new object [row, column];
When you are creating another Array just use this code:
object[,] clonedArray = (object[,]) newArray.Clone();
Simple! Have fun!

How to loop through and compare millions of values in two text files?

I have two text files files (TXT) which contain over 2 million distinct file names. I want to loop through all the names in the first file and find those that are also present in the second text file.
I have tried looping through the StreamReader but it takes a lot of time. I also tried the code below, but it still takes too much time.
StreamReader first = new StreamReader(path);
string strFirst = first.ReadToEnd();
string[] strarrFirst = strFirst.Split('\n');
bool found = false;
StreamReader second = new StreamReader(path2);
string str = second.ReadToEnd();
string[] strarrSecond = str.Split('\n');
for (int j = 0; j < (strarrFirst.Length); j++)
{
found = false;
for (int i = 0; i < (strarrSecond .Length); i++)
{
if (strarrFirst[j] == strarrSecond[i])
{
found = true;
break;
}
}
if (!found)
{
Console.WriteLine(strarrFirst[j]);
}
}
What is a good way to compare the files?
How about this:
var commonNames = File.ReadLines(path).Intersect(File.ReadLines(path2));
That's O(N + M) instead of your current solution which tests every line in the first file with every line in the second file - O(N * M).
That's assuming you're using .NET 4. Otherwise, you could use File.ReadAllLines, but that will read the whole file into memory. Or you could write the equivalent of File.ReadLines yourself - it's not terribly hard.
Ultimately you're likely to be limited by file IO by the time you've got rid of the O(N * M) problem in your current code - there's not much way to get round that.
EDIT: For .NET 2, first let's implement something like ReadLines:
public static IEnumerable<string> ReadLines(string file)
{
using (TextReader reader = File.OpenText(file))
{
string line;
while ((line = reader.ReadLine()) != null)
{
yield return line;
}
}
}
Now we really want to use a HashSet<T>, but that wasn't in .NET 2 - so let's use Dictionary<TKey, TValue> instead:
Dictionary<string, string> map = new Dictionary<string, string>();
foreach (string line in ReadLines(path))
{
map[line] = line;
}
List<string> intersection = new List<string>();
foreach (string line in ReadLines(path2))
{
if (map.ContainsKey(line))
{
intersection.Add(line);
}
}
Try something like this to speed it up a bit ...
var path = string.Empty;
var path2 = string.Empty;
var strFirst = string.Empty;
var str = string.Empty;
var strarrFirst = new List<string>();
var strarrSecond = new List<string>();
using (var first = new StreamReader(path))
{
strFirst = first.ReadToEnd();
}
using (var second = new StreamReader(path2))
{
str = second.ReadToEnd();
}
strarrFirst.AddRange(strFirst.Split('\n'));
strarrSecond.AddRange(str.Split('\n'));
strarrSecond.Sort();
foreach(var value in strarrFirst)
{
var found = strarrSecond.BinarySearch(value) >= 0;
if (!found) Console.WriteLine(value);
}
Just for fun, I've tried Jon Skeet method and own:
var guidArray = Enumerable.Range(0, 1000000).Select(x => Guid.NewGuid().ToString()).ToList();
string path = "first.txt";
File.WriteAllLines(path, guidArray);
string path2 = "second.txt";
File.WriteAllLines(path2, guidArray.Select(x=>DateTime.UtcNow.Ticks % 2 == 0 ? x : Guid.NewGuid().ToString()));
var start = DateTime.Now;
var commonNames = File.ReadLines(path).Intersect(File.ReadLines(path2)).ToList();
Console.WriteLine((DateTime.Now - start).TotalMilliseconds);
start = DateTime.Now;
var lines = File.ReadAllLines(path);
var hashset = new HashSet<string>(lines);
var lines2 = File.ReadAllLines(path2);
var result = lines2.Where(hashset.Contains).ToList();
Console.WriteLine((DateTime.Now - start).TotalMilliseconds);
Console.ReadKey();
And Skeet's method was tiny bit faster (1453.0831 vs 1488.0851, iDevForFun method was quite slow - 12791.7316), so i think under layers should happen same thing as I was trying to do manually with hashset.

How to create mutlidimensional list for this in 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);
}

Categories

Resources