taking data from a csv file, and putting it into an array - c#

public class Earthquake
{
public double Magnitude { get; set; }
public string Location { get; set; }
public double Latitude { get; set; }
public double Longitude { get; set; }
public double depth { get; set; }
public DateTime date { get; set; }
public string EventID { get; set; }
public string URL { get; set; }
public Earthquake()
: this(string.Empty, string.Empty, string.Empty, string.Empty, string.Empty, string.Empty, string.Empty, string.Empty)
{ }
public Earthquake(string magna, string locate, string lat, string longi, string dept, string dat, string Event, string website)
{
Magnitude = Convert.ToDouble(magna);
Location = locate;
Latitude = Convert.ToDouble(lat);
Longitude = Convert.ToDouble(longi);
depth = Convert.ToDouble(dept);
date = Convert.ToDateTime(dat);
EventID = Event;
URL = website;
}
}
public void GetData()
{
string[] text = File.ReadAllLines(#"Earthquakes.csv");
Earthquake[] data = new Earthquake[1];
foreach (string line in text)
{
string[] myColumns = line.Split(',');
Earthquake[] earth = new Earthquake[myColumns[0], myColumns[1], myColumns[2], myColumns[3], myColumns[4], myColumns[5], myColumns[6], myColumns[7]];
data[i] = earth[i];
i++;
}
}
Ignore commented parts I have those under control. The problem I am having is getting the data from the csv file into the Earthquake Array. I am getting syntax errors, and I know why, it's because the data type isn't correct, but I honestly cannot figure out how to fix it.
Also if you notice I am trying to use bubble sort and since there is no definition for "compare" for double, what do I use instead?

If your reading from CSV file you probably have to remove white space from the split values.
Try adding .Trim() to your column variables
myColumns[0].Trim()
if your looking to sort yor array consider using System.Linq
eg:
var byMag = earthQuakes.OrderBy(e => e.Magnitude);
Looking at your code you posted, GetData() will not work.
Try returning a list or Enumerable
public IEnumerable<Earthquake> GetData(string filename)
{
string[] text = File.ReadAllLines(filename);
foreach (string line in text)
{
string[] myColumns = line.Split(',');
yield return new Earthquake(myColumns[0].Trim(), myColumns[1].Trim(), myColumns[2].Trim(), myColumns[3].Trim(), myColumns[4].Trim(), myColumns[5].Trim(), myColumns[6].Trim(), myColumns[7].Trim());
}
}
Usage:
var earthquakes = GetData(#"Earthquakes.csv");

Related

How to retrieve only few columns data of a csv using the column names instead of column number in c#

I have a csv consisting of many columns. From that csv I have to select only few required columns.
The code I have written is
for (int i = 0; i < lineCount; i++)
{
var line = str.ReadLine();
if (line != null)
{
var values = line.Split(',');
dataInformation.Add(new DataInformation
{
timestamp_iso = values[3],
last_attributed_touch_data_tilde_campaign = values[9],
last_attributed_touch_data_tilde_channel = values[11],
last_attributed_touch_data_tilde_feature = values[12],
last_attributed_touch_data_tilde_ad_set_name = values[19],
user_data_platform = values[69],
user_data_aaid = values[70],
user_data_idfa = values[71],
user_data_idfv = values[72]
});
}
}
I am getting wrong values while using this. Is there any other approach to retrieve the values using the column names instead of column numbers.
The Data Information is a class
public class DataInformation
{
public string timestamp_iso { get; set; }
public string last_attributed_touch_data_tilde_campaign { get; set; }
public string last_attributed_touch_data_tilde_channel { get; set; }
public string last_attributed_touch_data_tilde_feature { get; set; }
public string last_attributed_touch_data_tilde_ad_set_name { get; set; }
public string user_data_platform { get; set; }
public string user_data_aaid { get; set; }
public string user_data_idfa { get; set; }
public string user_data_idfv { get; set; }
}
Please help me on this.
I recommend using a library to deal with CSV format. CsvHelper is a good one. It allows accessing fields by column name:
csv.Read();
var field = csv["HeaderName"];
CSV format may look simple, but there are a few corner cases (like quotes), so it is better to use an existing solution.
I have used the below code to get all the records of the type DataInformation.
using (TextReader fileReader = File.OpenText(FileName))
{
var csv = new CsvReader(fileReader);
dataInformation = csv.GetRecords<DataInformation>().ToList();
}
And after that I have used the below code to get the required columns.
using (TextWriter writer = new StreamWriter(ConfigurationManager.AppSettings["downloadFilePath"] + ConfigurationManager.AppSettings["fileName"] + date + ConfigurationManager.AppSettings["csvExtension"].ToString()))
{
using (var csv = new CsvWriter(TextWriter.Synchronized(writer)))
{
csv.WriteHeader(typeof(DataInformation));
csv.NextRecord();
csv.WriteRecords(dataInformation);
}
}
It works for me.

Iterate through array and add up elements with a control break logic

I am trying to use this for each loop to iterate through this array, and sum up the elements, 12, 10, 8, 7, and 6, when element 0 is not different (position.account), using control break logic,
This is furthering on a question I had earlier, but I can't seem to figure out how to do this logically.
static void Main(string[] args)
{
String path = #"C:\Users\jhochbau\documents\visual studio 2015\Projects\CsvReader\CsvReader\Position_2016_02_25.0415.csv";
//Adding lines read into a string[];
string[] lines = File.ReadAllLines(path);
foreach(string line in lines)
{
Positions position = new Positions();
string[] parsedLine = line.Split(',');
position.account = parsedLine[0];
position.settleMM = parsedLine[10];
position.open = parsedLine[6];
position.buy = parsedLine[7];
position.sell = parsedLine[8];
position.underlying = parsedLine[12];
//Need to convert these to an int.
//for each iteration through the loop where string[0] is already existing
//I want to have sum = sum + string[10]
}
Console.Read();
}
public class Positions
{
public string account { get; set; }
public string symbol { get; set; }
public string prevClose { get; set; }
public string curPrx { get; set; }
public string settlePX { get; set; }
public string Mult { get; set; }
public string open { get; set; }
public string buy { get; set; }
public string sell { get; set; }
public string netMM { get; set; }
public string settleMM { get; set; }
public string settleDay { get; set; }
public string underlying { get; set; }
}
Further to my comment, you could do something like this:
// store the accounts inside this dictionary
var accounts = new Dictionary<string, Positions>();
foreach(string line in lines)
{
Positions position = new Positions();
string[] parsedLine = line.Split(',');
position.account = parsedLine[0];
...
Positions existingAccount;
// if the account already exists in the dictionary
if (accounts.TryGetValue(position.account, out existingAccount)) {
existingAccount.buy += position.buy;
// do updating logic here
} else {
accounts.add(position.account, position);
// otherwise add it as a new element
}
}
Alternatively, you could go for Linq:
File.ReadLines(path)
.Select( line => new Position(line) )
.GroupBy( position => position.account )
.Select( group => new { Account = group.Key,
Sum = group.Select( position => position.settleMM ).Sum() } );

how to read a specific line in .csv file in WPF (xaml)

How can I code in wpf -xaml (C#) to read a specific line in a .csv File.
Every button on the Periodic table I made goes to a new window which shows in a listview the specific things about it. But then my question how to do that?
public class Atomic
{
public string Group { get; set; }
public string Period { get; set; }
public string Block { get; set; }
public string Atomicnumber { get; set; }
public string Stateat { get; set; }
public string Electronconfiguration { get; set; }
public string ChemspiderID { get; set; }
public Atomic(string group, string period, string block, string atomicnumber, string stateat, string electronconfiguration, string chemspiderID)
{
Group = group;
Period = period;
Block= block;
Atomicnumber = atomicnumber;
Stateat = stateat;
Electronconfiguration = electronconfiguration;
ChemspiderID = chemspiderID;
}
}
public IEnumerable<Atomic> ReadCSV(string fileName)
{
// We change file extension here to make sure it's a .csv file.
// TODO: Error checking.
string[] lines = File.ReadAllLines(System.IO.Path.ChangeExtension(fileName, ".csv"));
// lines.Select allows me to project each line as a Person.
// This will give me an IEnumerable<Person> back.
return lines.Select(line =>
{
string[] data = line.Split(';');
// We return a person with the data in order.
return new Atomic(data[0], data[1], data[2], data[3], data[4], data[5], data[6]);
});
}
If you want to read a specific line you could do the following.
public Atomic ReadCSV(string fileName, int lineIndex)
{
return File.ReadLines(System.IO.Path.ChangeExtension(fileName, ".csv"))
.Skip(lineIndex)
.Select(line => line.Split(';'))
.Select(data => new Atomic(data[0], data[1], data[2], data[3], data[4], data[5], data[6]))
.FirstOrDefault();
}
This will read the first lineNumber + 1 lines of the file take the last line read and create your Atomic object from that line. If there are not enough lines it will return a null value. If you prefer a one based index just change .Skip(lineIndex) to .Skip(lineIndex - 1).

convert json String to datatable?

While converting json string datatable facing an issue with , (comma) value in value field.
actualy my json string is [{"BNo":"345","GNo":"3453","FirstName":"fjai","LastName":"ljai","Address":"BARETI,CEVO, 13/2","Telephone":"051682247","BirthDate":"23-Jan-1981","Email":""}]
In that please look at the address scenario "Address":"BARETI,CEVO, 13/2"
It has the , in the values field. While converting the string to data base i got error. Here the code which i used convert json string to datatable
public DataTable JsonStringToDataTbl(string jsonString)
{
DataTable dt = new DataTable();
string[] jsonStringArray = Regex.Split(jsonString.Replace("[", "").Replace("]", ""), "},{");
List<string> ColumnsName = new List<string>();
foreach (string jSA in jsonStringArray)
{
string[] jsonStringData = Regex.Split(jSA.Replace("{", "").Replace("}", ""), ",");
foreach (string ColumnsNameData in jsonStringData)
{
try
{
int idx = ColumnsNameData.IndexOf(":");
string ColumnsNameString = ColumnsNameData.Substring(0, idx - 1).Replace("\"", "");
if (!ColumnsName.Contains(ColumnsNameString))
{
ColumnsName.Add(ColumnsNameString);
}
}
catch (Exception ex)
{
throw new Exception(string.Format("Error Parsing Column Name : {0}", ColumnsNameData));
}
}
break;
}
foreach (string AddColumnName in ColumnsName)
{
dt.Columns.Add(AddColumnName);
}
foreach (string jSA in jsonStringArray)
{
string[] RowData = Regex.Split(jSA.Replace("{", "").Replace("}", ""), ",");
DataRow nr = dt.NewRow();
foreach (string rowData in RowData)
{
try
{
int idx = rowData.IndexOf(":");
string RowColumns = rowData.Substring(0, idx - 1).Replace("\"", "");
string RowDataString = rowData.Substring(idx + 1).Replace("\"", "");
nr[RowColumns] = RowDataString;
}
catch (Exception ex)
{
continue;
}
}
dt.Rows.Add(nr);
}
return dt;
}
The code must omit the , in the value field.. what can i do
If your keys are unknown at the time of being read, then you can use the JObject and the JProperty classes from JSON.Net to retrieve the keys and their values like this:
private void printKeysAndValues(string json)
{
var jobject = (JObject)((JArray)JsonConvert.DeserializeObject(json))[0];
foreach (var jproperty in jobject.Properties())
{
Console.WriteLine("{0} - {1}", jproperty.Name, jproperty.Value);
}
}
Applied to two different JSON input string, retrieves the key/value pair:
var json1 = #"[{""BNo"":""345"",""GNo"":""3453"",""FirstName"":""fjai"",""LastName"":""ljai"",""Address"":""BARETI,CEVO, 13/2"",""Telephone"":""051682247"",""BirthDate"":""23-Jan-1981"",""Email"":""""}]";
var json2 = #"[{""Test"": ""A"", ""Text"":""some text"", ""Numbers"":""123""}]";
printKeysAndValues(json1);
Console.WriteLine("-------------------");
printKeysAndValues(json2);
And the output is:
BNo - 345
GNo - 3453
FirstName - fjai
LastName - ljai
Address - BARETI,CEVO, 13/2
Telephone - 051682247
BirthDate - 23-Jan-1981
Email -
-------------------
Test - A
Text - some text
Numbers - 123
One possibility would be to use the dynamic keyword. You can directly access the field like this:
var json = #"[{""BNo"":""345"",""GNo"":""3453"",""FirstName"":""fjai"",""LastName"":""ljai"",""Address"":""BARETI,CEVO, 13/2"",""Telephone"":""051682247"",""BirthDate"":""23-Jan-1981"",""Email"":""""}]";
dynamic data = JsonConvert.DeserializeObject(json);
// take the first element of the array
string address = data[0].Address;
Console.WriteLine(address.Replace(",", " "));
The output is:
BARETI CEVO 13/2
Note that String.Replace does not fail, if the symbol that should be replaced is not currently present, so "test".Replace(",", " "); will return test.
Another possibility is to use the in ASP.NET build in JSON converter (serializer/deserializer) - NewtonSoft JSON.Net. You can use it in order to regain the structured data. You need to create a class that represents the JSON structure:
public class Data
{
public string BNo { get; set; }
public string GNo { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Address { get; set; }
public string Telephones { get; set; }
public string BirthDates { get; set; }
public string Emails { get; set; }
}
Then the current JSON can be converted to an object of type Data using the JsonConvert.DeserializeObject method:
var json = #"[{""BNo"":""345"",""GNo"":""3453"",""FirstName"":""fjai"",""LastName"":""ljai"",""Address"":""BARETI,CEVO, 13/2"",""Telephone"":""051682247"",""BirthDate"":""23-Jan-1981"",""Email"":""""}]";
// remove square braces [ and ] at the start resp. end
var data = JsonConvert.DeserializeObject<Data>(json.Substring(1).Substring(0, json.Length - 2));
Now you can access the Address field and for example replace the , symbol:
Console.WriteLine(data.Address.Replace(",", " "));
The output is:
BARETI CEVO 13/2
I think your service returns also the wrong JSON format. JSON always starts with an object (when not in JavaScript), meaning that everything at the top level must be enclosed within curly braces { and }. If the service should return an array, then it should look like this {"results": [{"BNo":"...},{...}]}. If you can't change the service, then you can adapt / correct the returned string. Add a typed model for the array:
public class DataHolder
{
public Data[] data { get; set; }
}
and then create a correct JSON object holding an array:
var data = JsonConvert.DeserializeObject<DataHolder>("{\"data\":" + json + "}");
Console.WriteLine(data.data[0].Address.Replace(",", " "));
The output is again the same.
You can convert the JSON value to C# objects using Newtonsoft. This would be easy for you. Once you have converted to the below object, you can easily modify the Address property to remove the ',' value.
public class RootObject
{
public string BNo { get; set; }
public string GNo { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Address { get; set; }
public string Telephone { get; set; }
public string BirthDate { get; set; }
public string Email { get; set; }
}
Use the below line to convert to C# object
var jsonString = "The output of your webservice";
var obj = Newtonsoft.Json.JsonConvert.DeserializeObject<RootObject>(jsonString);
Now obj instance holds the C# object which is very easy to manipulate.

Using delimiters to separate string into variables

I have a list of string where each list item contains 6 values. Each value is separated by a comma. I want to use Split(',') to separate each value then assign each one to a variable
Do I have to use an array to create new variables, or is there a way to separate each value into existing variables?
Currently the code I have to do this is nothing but
foreach (String Item in ItemList)
{
string id="";
string slip = "";
string qty = "";
string itemEntered = "";
string UOM = "";
string desc = "";
string[] vars = Item.Split(',');
}
You just need to extract the split values by index:
string[] vars = line.Split(',');
string id = vars[0];
string slip = vars[1];
string Qty = vars[2];
string Item = vars[3];
string UOM = vars[4];
string Desc = vars[5];
Consider to use an available CSV-Parser instead of doing this manually. However, if your data never contains the separator and it's strict, your approach is fine. You just have to take the strings at the correct indices:
List<Data> data = new List<Data>();
foreach (String line in ItemList)
{
string[] vars = line.Split(',');
if (vars.Length == 6)
{
int id;
if(!int.TryParse(vars[0], out id))
continue;
string slip = vars[1];
int qty;
if(!int.TryParse(vars[2], out qty))
continue;
string item = vars[3];
string uom = vars[4];
string desc = vars[5];
data.Add(new Data { ID = id, Slip = vars[1], Quantity = qty, Desc = desc, Item = item, UOM = uom });
}
}
I have also used a custom class:
public class Data
{
public int ID { get; set; }
public string Slip { get; set; }
public int Quantity { get; set; }
public string Item { get; set; }
public string UOM { get; set; }
public string Desc { get; set; }
}

Categories

Resources