How to read and handle multiple lines which belong together? - c#

I am reading a file with a StreamReader. Now I want to read the cotent into a Dictionary<string, List<string>>
The file that I read looks like this:
'someKey'
Value1someKey
'anotherKey'
Value1another Value2anotherKey
I am at the point where I get the keys with following code
reactionInfo = new Dictionary<string, List<string>>();
string line;
StreamReader reader = new StreamReader(filePath);
while ((line = reader.ReadLine()) != null)
{
if (line.Trim().StartsWith("'"))
{
List<string> values = new List<string>();
if(!reactionInfo.TryGetValue(line,out values))
{
reactionInfo.Add(line, new List<string>());
}
}
}
How can I map the values of the next line to the key that is in the line above?

Read the next line in the loop to add those values while adding entry into dictionary. The below lines read the next line which can be added while adding.
var valuesStrings = reader.ReadLine().Split(' ');
Full Code:
reactionInfo = new Dictionary<string, List<string>>();
string line;
using(StreamReader reader = new StreamReader(filePath))
{
while ((line = reader.ReadLine()) != null)
{
if (line.Trim().StartsWith("'"))
{
List<string> values = new List<string>();
if(!reactionInfo.TryGetValue(line,out values))
{
var valuesStrings = reader.ReadLine().Split(' ');
reactionInfo.Add(line, values.Length > 0 ? new List<string>(new List<string>(valuesStrings)) : new List<string>());
}
}
}
}
Additional Suggestion :
Wrap the StreamReader into using block.

Keep a copy of your last read key, then use it to add the values in the next line.
reactionInfo = new Dictionary<string, List<string>>();
string line;
using (var reader = new StreamReader(filePath))
{
var lastKey= "";
while ((line = reader.ReadLine()) != null)
{
if (line.Trim().StartsWith("'"))
{
if(!reactionInfo.ContainsKey(line))
{
reactionInfo.Add(line, new List<string>());
lastKey = line;
}
}else
{
reactionInfo[lastKey].AddRange(line.Split(' ').ToList());
}
}
}

Related

Multiple List return using Tuple class in C#

I have a class Helper with 2 methods
public static List<string> GetCountryName()
{
List<string> CountryName = new List<string>();
using (var sr = new StreamReader(#"Country.txt"))
{
string line;
while ((line = sr.ReadLine()) != null)
{
int index = line.LastIndexOf(" ");
CountryName.Add(line.Substring(0, index));
}
}
return CountryName;
}
public static List<string> GetCountryCode()
{
List<string> CountryCode = new List<string>();
using (var sr = new StreamReader(#"Country.txt"))
{
string line;
while ((line = sr.ReadLine()) != null)
{
int index = line.LastIndexOf(" ");
CountryCode.Add(line.Substring(index + 1));
}
}
return CountryCode;
}
I bind these return values with my WPF ComboBox as follows
ddlCountryName.ItemsSource = Helper.GetCountryName();
ddlCountryCode.ItemsSource = Helper.GetCountryCode();
I wanted to return these List in a single method and went through these links
Tuple Class
https://stackoverflow.com/a/10278769
After going through it I tries like this but could not able to make it properly from line no-3 Tuple<List<string>> CountryName = new Tuple<List<string>>
public static Tuple<List<string>,List<string>> GetAllData()
{
Tuple<List<string>> CountryName = new Tuple<List<string>>
List<string> CountryCode = new List<string>();
using (var sr = new StreamReader(#"Country.txt"))
{
string line;
while ((line = sr.ReadLine()) != null)
{
int index = line.LastIndexOf(" ");
CountryName.Add(line.Substring(0, index));
CountryCode.Add(line.Substring(index + 1));
}
}
return CountryName;
return CountryCode;
}
Please help me to return List item wise and bind in the ItemsSource as per the below code
ddlCountryName.ItemsSource = Helper.GetCountryName();
try this (not tested)
public static Tuple<List<string>, List<string>> GetAllData()
{
List<string> CountryName = new List<string>();
List<string> CountryCode = new List<string>();
using (var sr = new StreamReader(#"Country.txt"))
{
string line;
while ((line = sr.ReadLine()) != null)
{
int index = line.LastIndexOf(" ");
CountryName.Add(line.Substring(0, index));
CountryCode.Add(line.Substring(index + 1));
}
}
return new Tuple<List<string>, List<string>>(CountryName,CountryCode);
}
A Tuple is a pack of two or more values and the types of these values are specified through generic parameters when you create a Tuple object. You are creating a Tuple of a single value, which has no meanings. Try creating it like this:
Tuple<List<string>, List<string>> CountryName = new Tuple<List<string>, List<string>>();
Also note that a function cannot have more than one return statements. You should add both your lists to the Tuple object and then return it in one go.
Your final function will be something like (keep your two existing functions and create a new function that calls them):
public static Tuple<List<string>,List<string>> GetAllData()
{
return new Tuple<List<string>, List<string>>(GetCountryName(), GetCountryCode());
}
An alternate approach:
public static List<Tuple<string, string>> GetAllData()
{
List<Tuple<string, string>> Result = new List<Tuple<string, string>>();
using (var sr = new StreamReader(#"Country.txt"))
{
string line;
while ((line = sr.ReadLine()) != null)
{
int index = line.LastIndexOf(" ");
var Name = line.Substring(0, index);
var Code = line.Substring(index + 1);
Result.Add(new Tuple<string, string>(Name, Code));
}
}
return Result;
}
In the first case, you do your binding directly to the Tuple members:
ddlCountryName.ItemsSource = Result.Item1;
ddlCountryCode.ItemsSource = Result.Item2;
In the second case, you can do some further linq to get your individual lists from the returned object:
ddlCountryName.ItemsSource = Result.Select(x => x.Item1).ToArray();
ddlCountryCode.ItemsSource = Result.Select(x => x.Item2).ToArray();

How to read a file into a hashmap or dictionary in c#

I have a file with values like this
keyA: Value1
keyB: Value2
keyC: Value3
Is there a easy way to consume this file in c# so that I have it in a hashmap or something similar?
You can use File.ReadLines method to read the lines,split the lines with Split method and put them into dictionary using ToDictionary:
var dict = File.ReadLines("path")
.ToDictionary(x => x.Split(':')[0], x => x.Split(':')[1]);
Try this:
public IDictionary<string, string> ReadFromFile(string fileName)
{
var result = new Dictionary<string, string>();
using (var file = new StreamReader(fileName))
{
string line;
while ((line = file.ReadLine()) != null)
{
var values = line.Split(':');
if (values.Length == 2)
{
result[values[0].Trim()] = values[1].Trim();
}
}
}
return result;
}

How to skip headline in csv data when reading from StreamReader?

EDITED:
I have following code:
private void button1_Click_1(object sender, EventArgs e)
{
var date = new List<String>();
var value = new List<Double>();
string dir = #"C:\Main\test.csv";
using (var reader = new System.IO.StreamReader(dir))
{
var lines = File.ReadLines(dir)
.Skip(1);//Ignore the first line
foreach (var line in lines)
{
var fields = line.Split(new Char[] { ';' }, StringSplitOptions.RemoveEmptyEntries);
date.Add(fields[0]);
if (fields.Length > 1)
value.Add(Convert.ToDouble(fields[1]));
}
String[] _date = date.ToArray();
Double[] _value = value.ToArray();
chart1.Series["Test"].Points.DataBindXY(_date,_value);
chart1.Series["Test"].ChartType = SeriesChartType.Spline;
}
}
Now I want to skip the headline of the csv data. That means the first row of the first column and the first row of the second column. How to do that?
The headlines are Strings.When no headlines are in, he will skip the first row but with headlines I get a System.FormatException.
It fails when the first row contains Date in the first column and Value in the second column like that (opened with texteditor):
"Date";"Value"
"20.04.2010";"82.6619508214314"
"21.04.2010";"33.2262968571519"
"22.04.2010";"25.0174973120814"
Why not just start by reading one line, and doing nothing with it?
using (var reader = new System.IO.StreamReader(dir))
{
reader.ReadLine(); // skip first
string line;
while ((line = reader.ReadLine()) != null)
{
}
}
Add one reader.ReadLine() before doing the while loop
using (var reader = new System.IO.StreamReader(dir))
{
if (reader.ReadLine()) //read first line
{
string line;
while ((line = reader.ReadLine()) != null) //read following lines
{
}
}
}

Adding a string to a List<string> inside of a List<List<string>>

Im trying to add a string object to a list inside of list> in a for & while loop, trying to use var i as the list object i wish to use.
here is the code of the class, any help on what im doing wrong would be very much appreciated :)
public class GenClass
{
private static int _genCount;
private static bool _filesLoadedToLists;
private static List<string> _nounSetOne = new List<string>();
private static List<string> _nounSetTwo = new List<string>();
private static List<List<string>> _toLoad = new List<List<string>>();
private string _emotionMidTrim = "";
public const string FileOne = "NounSetOne.txt";
public const string FileTwo = "NounSetTwo.txt";
public GenClass()
{
while (_filesLoadedToLists == false)
{
TextToList(FileOne,FileTwo);
_filesLoadedToLists = true;
}
_genCount++;
}
the problem is withing this part of the class
public void TextToList(string fileOne, string fileTwo)
{
List<string> filesToRead = new List<string>();
filesToRead.Add(fileOne); // Add the text files to read to a list
filesToRead.Add(fileTwo); // Add the text files to read to a list
_toLoad.Add(_nounSetOne); // Add a list of words to this list
_toLoad.Add(_nounSetTwo); // Add a list of words to this list
for (int i = 0; i <= filesToRead.Count; i++)
{
using (var reader = new StreamReader(filesToRead[i]))
{
string line;
while ((line = reader.ReadLine()) != null)
{
_toLoad[i.Add(line)]; // the error is here
}
}
}
Try using File.ReadAllLines(). Replace the for loop with:
foreach(var file in filesToRead) {
_toLoad.Add(File.ReadAllLines(file).ToList());
}
You are correct, with the error, you need to understand that the
List<List<string>> will take a List<string> and NOT A String.
Try something like this;
List<string> listOfString = new List<string>;
for (int i = 0; i <= filesToRead.Count; i++)
{
using (var reader = new StreamReader(filesToRead[i]))
{
string line;
while ((line = reader.ReadLine()) != null)
{
listOfString.add(line);
}
}
}
Then,
_toLoad.add(listOfStrings);
You can cut this down considerably using LINQ:
List<string> filesToRead = new List<string> {"NounSetOne.txt", "NounSetTwo.txt"};
List<List<string>> _toLoad = new List<List<string>>();
_toLoad.AddRange(filesToRead.Select(f => File.ReadAllLines (f).ToList() ));
Note that there's no extraneous variables for the filename (why have FileOne/FileTwo if their only purpose is to get added to a list?) and that we're letting the AddRange take care of creating the List<string>s for us automatically.
for (int i = 0; i <= filesToRead.Count; i++)
{
using (var reader = new StreamReader(filesToRead[i]))
{
string line;
while ((line = reader.ReadLine()) != null)
{
_toLoad[i].Add(line);
}
}
}

Reading file with C#

I want to read php text file using c#. The file looks like:
2.20:2.20:2.20:2.20:2.20:
2012-07-12:2012-07-11:2012-07-10:2012-07-09:2012-07-08:
I would like to get all lines to listboxes. In real situation there is six lines, but first I should have read these two lines. My code:
void web_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e)
{
try
{
int i;
string price_line = "";
string date_line = "";
List<decimal> prices = new List<decimal>();
List<string> dates = new List<string>();
using (var reader = new StreamReader(e.Result))
{
price_line = reader.ReadLine();
date_line = reader.ReadLine();
string[] bit_1 = price_line.Split(':');
string[] bit_2 = date_line.Split(':');
for (i = 0; i < 2; i++)
{
prices.Add(decimal.Parse(bit_1[i]));
dates.Add(bit_2[i]);
}
listBox1.ItemsSource = prices;
listBox2.ItemsSource = dates;
}
}
catch
{
MessageBox.Show("Can't read!");
}
}
Now I get "NullException". How to fix this?
EDIT:
What's about:
using (StreamReader reader = new StreamReader(e.Result))
{
List<string> lines = new List<string>();
while (!reader.EndOfStream)
lines.Add(reader.ReadLine());
string prices = lines.First().Split(':');
List<decimal> listPrices = new List<decimal>();
List<string> listDates = lines.Last().Split(':').ToList();
foreach(string s in prices)
listPrices.Add(double.Parse(s));
listBox1.ItemsSource = listPrices;
listBox2.ItemsSource = listDates;
}
You should check if e.Result, listBox1 and listBox2 aren't null.

Categories

Resources