I have to parse a TSV file which has the following structure:
[Secti
"1 2"
"2 3"his?
I'm not sure if this is what you were trying to do or not. I also noticed that it appeared to be 4 spaces between records. If it is actually a tab, you can change the delimiter to a tab Delimiter = "\t",
void Main()
{
var data = #"[Section one of info]
""Atr1 1""
""Atr2 2""
[Section two of info]
""Atr3 Atr4""
""1 2""
""2 3""
""4 5""";
var config = new CsvConfiguration(CultureInfo.InvariantCulture)
{
Delimiter = " ",
Mode = CsvMode.Escape
};
using (var reader = new StringReader(data))
using (var csv = new CsvReader(reader, config))
{
var isSectionOne = true;
var record = new Foo() { Atr3 = new List<int>(), Atr4 = new List<int>() };
while(csv.Read())
{
if (csv.GetField(0).StartsWith("["))
continue;
if (isSectionOne)
{
if (csv.GetField(0) == "Atr1")
{
record.Atr1 = csv.GetField<int>(1);
}
if (csv.GetField(0) == "Atr2")
{
record.Atr2 = csv.GetField<int>(1);
}
if (csv.GetField(0) == "Atr3")
{
isSectionOne = false;
}
}
else
{
record.Atr3.Add(csv.GetField<int>(0));
record.Atr4.Add(csv.GetField<int>(1));
}
}
record.Dump();
}
}
public class Foo
{
public int Atr1 { get; set; }
public int Atr2 { get; set; }
public List<int> Atr3 { get; set; }
public List<int> Atr4 { get; set; }
}
Related
I am trying to create an json data similar to this https://cdn.jsdelivr.net/gh/highcharts/highcharts#v7.0.0/samples/data/world-mortality.json
The current output I am getting is like this. The model name is being displayed and child does not seems to work. is t possible to remove the model field name on the serialize?
[{Name:"ABC",
Firstchild:[{Name:"AIR IMPORT",
Secondchild:[{NAME:"SCMBOA00052997",VALUE:69.7500},
{NAME:"SH123",VALUE:-100.0000},
{NAME:"SH456",VALUE:50.0000},
{NAME:"SH789",VALUE:150.0000}]
}]
}{Name:"DEF",
Firstchild:[{Name:"AIR IMPORT",
Secondchild:[{NAME:"SCMBOA00052997",VALUE:69.7500},
{NAME:"SH111",VALUE:-10.0000},
{NAME:"SH222",VALUE:80.0000},
{NAME:"SH333",VALUE:160.0000}]
}]
}]
What I need is like this
{
"ABC": {
"AIR IMPORT":{
"SH123": -100.0000,
"SH456": 50.0000,
"SH789": 150.0000
}
},
"DEF": {
"AIR IMPORT":{
"SH111": -10.0000,
"SH222": 80.0000,
"SH333": 160.0000
}
}
}
MODEL
public class ParentTreemap
{
public string Name { get; set; }
public List<FirstChildTreemap> Firstchild { get; set; }
}
public class FirstChildTreemap
{
public string Name { get; set; }
public List<SecondChildTreemap> Secondchild { get; set; }
}
public class SecondChildTreemap
{
[JsonProperty]
public string Name { get; set; }
[JsonProperty]
public decimal Value { get; set; }
}
Controller
var parent = treemaplist.Where(s => s.Parent == 0);
List<ParentTreemap> plist = new List<ParentTreemap>();
foreach (var item in parent)
{
var firstchild = treemaplist.Where(s => s.Parent == item.Id && s.Value==0);
List<FirstChildTreemap> flist = new List<FirstChildTreemap>();
foreach (var fitem in firstchild)
{
var secondchild = treemaplist.Where(s => s.Parent == fitem.Id && s.Value!=0);
List<SecondChildTreemap> slist = new List<SecondChildTreemap>();
foreach (var sitem in secondchild)
{
SecondChildTreemap model = new SecondChildTreemap();
model.Name = sitem.Name;
model.Value = sitem.Value;
slist.Add(model);
}
FirstChildTreemap child = new FirstChildTreemap();
child.Name = fitem.Name;
child.Secondchild = slist;
flist.Add(child);
}
ParentTreemap pmodel = new ParentTreemap();
pmodel.Name = item.Name;
pmodel.Firstchild = flist;
plist.Add(pmodel);
}
var stringWriter = new StringWriter();
var serializer = new JsonSerializer();
using (var writer = new JsonTextWriter(stringWriter))
{
writer.QuoteName = false;
serializer.Serialize(writer, plist);
}
ViewData["result"] = stringWriter;
I'm trying to build objects based on xmlreader:
List<Element> units = new List<Element>();
string path = "D:\\Item\\Unit.xml";
XElement xelement = XElement.Load(path);
IEnumerable<XElement> elements = xelement.Elements();
foreach (var c in elements)
{
Element stb = new Element();
stb.Name = c.Element("Name").Value;
stb.Picture = c.Element("Picture").Value;
//and next 30 options included try / catch for int.Parse
}
XML:
<?xml version="1.0" encoding="UTF-8"?>
<rows>
<row id="1">
<Name>Freighter</Name>
<Picture>Item\Freighter.gif</Picture>
... and 30 next rows with data for each "unit"
</row>
... and 30 next units...
<rows>
As I told, XML is 23kB file with 30 rows per each unit, with total 30 units in file. Not sure why this code is so slow: it took 670 miliseconds (i3 processor).
The slowest part is obiect fillig, but not sure how to improve it.
The complete code looks exactly:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
using System.Diagnostics;
namespace element_reader
{
class Program
{
static void Main(string[] args)
{
CustomStopwatch sw = new CustomStopwatch();
sw.Start();
List<Element> ships = new List<Element>();
string path = "D:\\Ship_test.xml";
XElement xelement = XElement.Load(path);
IEnumerable<XElement> elements = xelement.Elements();
sw.Stop();
Console.WriteLine("Stopwatch elapsed: {0}, StartAt: {1}, EndAt: {2}", sw.ElapsedMilliseconds, sw.StartAt.Value, sw.EndAt.Value);
sw.Start();
foreach (var c in elements)
{
Element stb = new Element();
stb.Name = c.Element("Name").Value;
stb.Picture = c.Element("Picture").Value;
try
{
stb.Prt = int.Parse(c.Element("PRT").Value);
}
catch
{ stb.Prt = 0; }
try
{
stb.Lrt = int.Parse(c.Element("LRT").Value);
}
catch
{ stb.Lrt = 0; }
stb.Special = c.Element("Special").Value;
try
{
stb.Wep = int.Parse(c.Element("Wep").Value);
}
catch
{ stb.Wep = 0; }
try
{
stb.Con = int.Parse(c.Element("Con").Value);
}
catch
{ stb.Con = 0; }
try
{
stb.Ene = int.Parse(c.Element("Ene").Value);
}
catch
{ stb.Ene = 0; }
try
{
stb.Ele = int.Parse(c.Element("Ele").Value);
}
catch
{ stb.Ele = 0; }
try
{
stb.Prp = int.Parse(c.Element("Prp").Value);
}
catch
{ stb.Prp = 0; }
try
{
stb.Bio = int.Parse(c.Element("Bio").Value);
}
catch
{ stb.Bio = 0; }
try
{
stb.Mass = int.Parse(c.Element("Mass").Value);
}
catch
{ stb.Mass = 0; }
try
{
stb.Iro = int.Parse(c.Element("Iro").Value);
}
catch
{ stb.Iro = 0; }
try
{
stb.Bor = int.Parse(c.Element("Bor").Value);
}
catch
{ stb.Bor = 0; }
try
{
stb.Ger = int.Parse(c.Element("Ger").Value);
}
catch
{ stb.Ger = 0; }
try
{
stb.Res = int.Parse(c.Element("Res").Value);
}
catch
{ stb.Res = 0; }
ships.Add(stb);
}
sw.Stop();
Console.WriteLine("Stopwatch elapsed: {0}, StartAt: {1}, EndAt: {2}", sw.ElapsedMilliseconds, sw.StartAt.Value, sw.EndAt.Value);
Console.Read();
}
}
public class Element
{
public string Name;
public string Picture;
public int Prt;
public int Lrt;
public string Special;
public int Con;
public int Wep;
public int Ene;
public int Ele;
public int Prp;
public int Bio;
public int Mass;
public int Iro;
public int Bor;
public int Ger;
public int Res;
}
public class CustomStopwatch : Stopwatch
{
public DateTime? StartAt { get; private set; }
public DateTime? EndAt { get; private set; }
public void Start()
{
StartAt = DateTime.Now;
base.Start();
}
public void Stop()
{
EndAt = DateTime.Now;
base.Stop();
}
}
}
When the part of XML looks exactly:
<?xml version="1.0" encoding="UTF-8"?>
<rows>
<row id="1">
<Name>Small Freighter</Name>
<Picture>Item\Ship\Ship01_1.gif</Picture>
<Description></Description>
<PRT></PRT>
<LRT></LRT>
<Special></Special>
<Ene>0</Ene>
<Wep>0</Wep>
<Prp>0</Prp>
<Con>0</Con>
<Ele>0</Ele>
<Bio>0</Bio>
<Slot1>-150, 0, Engine, 1, 1, 1</Slot1>
<Slot2>-50, 0, Cargo, 70, 1, 1</Slot2>
<Slot3>50, 0, DEF, 1, 1, 1</Slot3>
<Slot4>150, 0, SEM, 1, 1, 1</Slot4>
<Mass>25</Mass>
<Res>20</Res>
<Iro>12</Iro>
<Res>0</Res>
<Ger>17</Ger>
<Fuel>130</Fuel>
<Cargo>70</Cargo>
<HPD_arm>25</HPD_arm>
<Initiative>0</Initiative>
</row>
</rows>
Result is 70ms for 1kB file !!!
If I have 20 files to load with 20-30 rows each this method is completely useless.
Please notice that I do not use all data located in file.
You didn't provide full xml file content, so I just only can suggest you one thing.
Use int.TryParse instead of int.Parse. I bet your code throws hundreds of exceptions which are very CPU expensive.
Usually the code should look like this :
List<Element> elements = xelement.Descendants("TagName").Select(x => new Element() {
Name = (string)x.Element("Name"),
Picture = (string)x.Element("Picture")
}).ToList();
Here is the comparison of the times
Time 1 = '11.0082', Time 2 = '4.0032'
Here is code :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
using System.Xml.Serialization;
namespace ConsoleApplication1
{
class Program
{
const string FILENAME = #"c:\temp\test.xml";
static void Main(string[] args)
{
Element newElement = new Element() {
Name = "John",
Picture = "Dorian Grey",
Data1 = "1",
Data2 = "1",
Data3 = "1",
Data4 = "1",
Data5 = "1",
Data6 = "1",
Data7 = "1",
Data8 = "1",
Data9 = "1",
Data10 = "1",
Data11 = "1",
Data12 = "1",
Data13 = "1",
Data14 = "1",
Data15 = "1",
Data16 = "1",
Data17 = "1",
Data18 = "1",
Data19 = "1",
Data20 = "1",
Data21 = "1",
Data22 = "1",
Data23 = "1",
Data24 = "1",
Data25 = "1",
Data26 = "1",
Data27 = "1",
Data28 = "1",
Data29 = "1",
Data30 = "1"
};
Root root = new Root();
for (int i = 0; i < 29; i++)
{
root.elements.Add(newElement);
}
XmlWriterSettings setting = new XmlWriterSettings();
setting.Indent = true;
XmlWriter writer = XmlWriter.Create(FILENAME, setting);
XmlSerializer serializer = new XmlSerializer(typeof(Root));
serializer.Serialize(writer, root);
writer.Flush();
writer.Close();
XDocument doc = XDocument.Load(FILENAME);
DateTime start1 = DateTime.Now;
List<Element> units = new List<Element>();
List<XElement> elements = doc.Root.Elements().ToList();
foreach (var c in elements)
{
Element stb = new Element();
stb.Name = c.Element("Name").Value;
stb.Picture = c.Element("Picture").Value;
stb.Data1 = c.Element("Data1").Value;
stb.Data2 = c.Element("Data2").Value;
stb.Data3 = c.Element("Data3").Value;
stb.Data4 = c.Element("Data4").Value;
stb.Data5 = c.Element("Data5").Value;
stb.Data6 = c.Element("Data6").Value;
stb.Data7 = c.Element("Data7").Value;
stb.Data8 = c.Element("Data8").Value;
stb.Data9 = c.Element("Data9").Value;
stb.Data10 = c.Element("Data10").Value;
stb.Data11 = c.Element("Data11").Value;
stb.Data12 = c.Element("Data12").Value;
stb.Data13 = c.Element("Data13").Value;
stb.Data14 = c.Element("Data14").Value;
stb.Data15 = c.Element("Data15").Value;
stb.Data16 = c.Element("Data16").Value;
stb.Data17 = c.Element("Data17").Value;
stb.Data18 = c.Element("Data18").Value;
stb.Data19 = c.Element("Data19").Value;
stb.Data20 = c.Element("Data20").Value;
stb.Data21 = c.Element("Data21").Value;
stb.Data22 = c.Element("Data22").Value;
stb.Data23 = c.Element("Data23").Value;
stb.Data24 = c.Element("Data24").Value;
stb.Data25 = c.Element("Data25").Value;
stb.Data26 = c.Element("Data26").Value;
stb.Data27 = c.Element("Data27").Value;
stb.Data28 = c.Element("Data28").Value;
stb.Data29 = c.Element("Data29").Value;
stb.Data30 = c.Element("Data30").Value;
units.Add(stb);
}
DateTime end1 = DateTime.Now;
DateTime start2 = DateTime.Now;
List<Element> elements2 = doc.Descendants("elements").Select(x => new Element()
{
Name = (string)x.Element("Name"),
Picture = (string)x.Element("Picture"),
Data1 = (string)x.Element("Data1"),
Data2 = (string)x.Element("Data2"),
Data3 = (string)x.Element("Data3"),
Data4 = (string)x.Element("Data4"),
Data5 = (string)x.Element("Data5"),
Data6 = (string)x.Element("Data6"),
Data7 = (string)x.Element("Data7"),
Data8 = (string)x.Element("Data8"),
Data9 = (string)x.Element("Data9"),
Data10 = (string)x.Element("Data10"),
Data11 = (string)x.Element("Data11"),
Data12 = (string)x.Element("Data12"),
Data13 = (string)x.Element("Data13"),
Data14 = (string)x.Element("Data14"),
Data15 = (string)x.Element("Data15"),
Data16 = (string)x.Element("Data16"),
Data17 = (string)x.Element("Data17"),
Data18 = (string)x.Element("Data18"),
Data19 = (string)x.Element("Data19"),
Data20 = (string)x.Element("Data20"),
Data21 = (string)x.Element("Data21"),
Data22 = (string)x.Element("Data22"),
Data23 = (string)x.Element("Data23"),
Data24 = (string)x.Element("Data24"),
Data25 = (string)x.Element("Data25"),
Data26 = (string)x.Element("Data26"),
Data27 = (string)x.Element("Data27"),
Data28 = (string)x.Element("Data28"),
Data29 = (string)x.Element("Data29"),
Data30 = (string)x.Element("Data30"),
}).ToList();
DateTime end2 = DateTime.Now;
string results = string.Format("Time 1 = '{0}', Time 2 = '{1}'", (end1 - start1).TotalMilliseconds, (end2 - start2).TotalMilliseconds);
Console.ReadLine();
}
}
public class Root
{
[XmlElement]
public List<Element> elements = new List<Element>();
}
public class Element
{
public string Name { get; set; }
public string Picture { get; set; }
public string Data1 { get; set; }
public string Data2 { get; set; }
public string Data3 { get; set; }
public string Data4 { get; set; }
public string Data5 { get; set; }
public string Data6 { get; set; }
public string Data7 { get; set; }
public string Data8 { get; set; }
public string Data9 { get; set; }
public string Data10 { get; set; }
public string Data11 { get; set; }
public string Data12 { get; set; }
public string Data13 { get; set; }
public string Data14 { get; set; }
public string Data15 { get; set; }
public string Data16 { get; set; }
public string Data17 { get; set; }
public string Data18 { get; set; }
public string Data19 { get; set; }
public string Data20 { get; set; }
public string Data21 { get; set; }
public string Data22 { get; set; }
public string Data23 { get; set; }
public string Data24 { get; set; }
public string Data25 { get; set; }
public string Data26 { get; set; }
public string Data27 { get; set; }
public string Data28 { get; set; }
public string Data29 { get; set; }
public string Data30 { get; set; }
}
}
I would like to make a method to print a LINQ (table) with all its properties and values to the console.
I'm currently trying to do this via the System.Reflection.GetType().GetProperties()
What I think is going wrong is the type of parameter I try to send to the method. If possible this should be a var so I can use this method with any class list. (not sure if this is possible)
The issue is with the printtabel() method.
I started from:
Print a table with LINQ
namespace LINQ
{
class Program
{
public class Bier
{
public int BierNr { get; set; }
public string Biernaam { get; set; }
public float Alcohol { get; set; }
public Brouwer Brouwer { get; set; } //associatie met een brouwer
public override string ToString() { return Biernaam + ": " + Alcohol + "% alcohol"; }
}
public class Brouwer
{
public int BrouwerNr { get; set; }
public string Brouwernaam { get; set; }
public bool Belgisch { get; set; }
public List<Bier> Bieren { get; set; }
public override string ToString() { return "Brouwerij " + Brouwernaam + " (" + (Belgisch ? "Belgisch" : "Niet Belgisch") + ")"; }
}
public class Brouwers
{
public List<Brouwer> GetBrouwers()
{
List<Brouwer> lijst = new List<Brouwer>();
Brouwer palm = new Brouwer { BrouwerNr = 1, Brouwernaam = "Palm", Belgisch = true };
palm.Bieren = new List<Bier> {
new Bier {BierNr=1,Biernaam="Palm Dobbel", Alcohol=6.2F, Brouwer=palm},
new Bier {BierNr=2, Biernaam="Palm Green", Alcohol=0.1F, Brouwer=palm},
new Bier {BierNr=3, Biernaam="Palm Royale", Alcohol=7.5F, Brouwer=palm}
};
lijst.Add(palm);
Brouwer hertogJan = new Brouwer { BrouwerNr = 2, Brouwernaam = "Hertog Jan", Belgisch = false };
hertogJan.Bieren = new List<Bier> {
new Bier{ BierNr=4, Biernaam="Hertog Jan Dubbel", Alcohol=7.0F, Brouwer=hertogJan},
new Bier{ BierNr=5, Biernaam="Hertog Jan Grand Prestige", Alcohol=10.0F, Brouwer=hertogJan} };
lijst.Add(hertogJan);
Brouwer inBev = new Brouwer { BrouwerNr = 3, Brouwernaam = "InBev", Belgisch = true };
inBev.Bieren = new List<Bier> {
new Bier { BierNr=6, Biernaam="Belle-vue kriek L.A", Alcohol=1.2F, Brouwer=inBev},
new Bier { BierNr=7, Biernaam="Belle-vue kriek", Alcohol=5.2F, Brouwer=inBev},
new Bier { BierNr=8, Biernaam="Leffe Radieuse", Alcohol=8.2F,Brouwer=inBev},
new Bier { BierNr=9, Biernaam="Leffe Triple", Alcohol=8.5F,Brouwer=inBev} };
lijst.Add(inBev);
//return new List<Brouwer> { palm, hertogJan, inBev };
return lijst;
}
}
static void Main(string[] args)
{
var brouwers = new Brouwers().GetBrouwers();
var belgischeBrouwerijenMet3Bieren =
from brouwer in brouwers
where brouwer.Belgisch && brouwer.Bieren.Count == 3
select brouwer;
foreach (var brouwer in belgischeBrouwerijenMet3Bieren)
Console.WriteLine(brouwer.Brouwernaam);
var bieren = from brouwer in brouwers
from bier in brouwer.Bieren
select bier;
string vorigeBrouwer = "";
foreach (var bier in bieren)
{
if (bier.Brouwer.ToString() != vorigeBrouwer)
{
Console.WriteLine(bier.Brouwer);
vorigeBrouwer = bier.Brouwer.ToString();
}
Console.WriteLine($"\t {bier.ToString()}");
}
Console.WriteLine(printtabel(belgischeBrouwerijenMet3Bieren));
Console.ReadLine();
}
public string printtabel(IEnumerable<Brouwer> response)
{
StringBuilder sb = new StringBuilder();
foreach (PropertyInfo prop in response.GetType().GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance))
{
object value = prop.GetValue(response, new object[] { });
sb.AppendLine($"{prop.Name} = {value}");
}
return sb.ToString();
}
}
}
Error CS0120 An object reference is required for the non-static field, method, or property 'Program.printtabel(IEnumerable)' LINQ 204 Active
You can fix it by writing:
public static string printtabel(IEnumerable<Brouwer> response)
You are calling a non static method from a static method. Set printtabel static and this error should disappear.
namespace Calendar
{
public partial class MainCalendar : Form
{
private JArray items;
private List<String> AMList = new List<String>();
private List<String> PMList = new List<String>();
private List<String> accessToCalendarFilepath = new List<String>();
private List<CalendarModel> people;
private List<List<CalendarModel>> managers = new List<List<CalendarModel>>();
private List<String> userSelection = new List<String>();
private bool authorizedAccess = false;
private String javaScriptFileContainingJSONObject = "";
public MainCalendar()
{
InitializeComponent();
var locationInformation = System.Environment.CurrentDirectory + Path.DirectorySeparatorChar + "location.json";
using (StreamReader file = File.OpenText(locationInformation))
using (JsonTextReader reader = new JsonTextReader(file))
{
JArray o = (JArray)JToken.ReadFrom(reader);
items = o;
}
foreach (var item in items.Children())
{
var itemProperties = item.Children<JProperty>();
// you could do a foreach or a linq here depending on what you need to do exactly with the value
var myElement = itemProperties.FirstOrDefault(x => x.Name == "name");
var myElementValue = myElement.Value; ////This is a JValue type
if(myElementValue.ToString().Contains("AM"))
{
AMList.Add(myElementValue.ToString());
}
if (myElementValue.ToString().Contains("PM"))
{
PMList.Add(myElementValue.ToString());
}
}
mondayAM.DataSource = AMList.ToArray();
tuesdayAM.DataSource = AMList.ToArray();
wednesdayAM.DataSource = AMList.ToArray();
thursdayAM.DataSource = AMList.ToArray();
fridayAM.DataSource = AMList.ToArray();
mondayPM.DataSource = PMList.ToArray();
tuesdayPM.DataSource = PMList.ToArray();
wednesdayPM.DataSource = PMList.ToArray();
thursdayPM.DataSource = PMList.ToArray();
fridayPM.DataSource = PMList.ToArray();
loadAccessControl("accesscontrol.json");
dateTimePicker1.AlwaysChooseMonday(dateTimePicker1.Value);
String dateSelected = dateTimePicker1.Value.ToShortDateString();
findManagerForSelectedDate(dateSelected);
}
public void loadAccessControl(String fileName)
{
var accessControlInformation = Environment.CurrentDirectory + Path.DirectorySeparatorChar + fileName;
List<AccessControl> accounts = JsonConvert.DeserializeObject<List<AccessControl>>(File.ReadAllText(accessControlInformation));
foreach (AccessControl account in accounts)
{
Console.WriteLine(account.accountName);
if (account.accountName.ToLower().Contains(Environment.UserName.ToLower()))
{
foreach (CalendarFile file in account.files)
{
// Console.WriteLine(Environment.CurrentDirectory + Path.DirectorySeparatorChar + "content" + Path.DirectorySeparatorChar + file.Filename);
accessToCalendarFilepath.Add(Environment.CurrentDirectory + Path.DirectorySeparatorChar + "content" + Path.DirectorySeparatorChar + file.Filename);
}
break;
}
}
contentsOfFile();
}
private void contentsOfFile()
{
String line;
foreach(var file in accessToCalendarFilepath)
{
StreamReader contentsOfJSONFile = new StreamReader(file);
while((line = contentsOfJSONFile.ReadLine()) != null)
{
if(line.Contains("var "))
{
javaScriptFileContainingJSONObject = javaScriptFileContainingJSONObject + "[";
}
else if(line.Contains("];"))
{
javaScriptFileContainingJSONObject = javaScriptFileContainingJSONObject + "]";
}
else
{
javaScriptFileContainingJSONObject = javaScriptFileContainingJSONObject + line;
}
}
people = JsonConvert.DeserializeObject<List<CalendarModel>>((string)javaScriptFileContainingJSONObject);
managers.Add(people);
javaScriptFileContainingJSONObject = "";
}
}
private void findManagerForSelectedDate(String dateSelected)
{
dateSelected = dateTimePicker1.Value.ToShortDateString();
List<String> managerNames = new List<String>();
foreach(var item in managers)
{
foreach (var subitem in item)
{
CalendarModel c = subitem;
Console.WriteLine(c.date);
c.name = new CultureInfo("en-US", false).TextInfo.ToTitleCase(c.name);
if (userSelection.Count > 0)
{
foreach (var addedUser in userSelection.ToArray())
{
if (!addedUser.Contains(c.name))
{
userSelection.Add(c.name); // CRASHING HERE
//{"Exception of type 'System.OutOfMemoryException' was thrown."}
}
}
}
else
{
userSelection.Add(c.name);
}
}
}
Console.WriteLine();
}
I keep running out of memory.
The CalendarModel class:
namespace Calendar
{
class CalendarModel
{
[JsonProperty("name")]
public string name { get; set; }
[JsonProperty("date")]
public string date { get; set; }
[JsonProperty("title")]
public string title { get; set; }
[JsonProperty("mondayAM")]
public string mondayAM { get; set; }
[JsonProperty("mondayPM")]
public string mondayPM { get; set; }
[JsonProperty("tuesdayAM")]
public string tuesdayAM { get; set; }
[JsonProperty("tuesdayPM")]
public string tuesdayPM { get; set; }
[JsonProperty("wednesdayAM")]
public string wednesdayAM { get; set; }
[JsonProperty("wednesdayPM")]
public string wednesdayPM { get; set; }
[JsonProperty("thursdayAM")]
public string thursdayAM { get; set; }
[JsonProperty("thursdayPM")]
public string thursdayPM { get; set; }
[JsonProperty("fridayAM")]
public string fridayAM { get; set; }
[JsonProperty("fridayPM")]
public string fridayPM { get; set; }
[JsonProperty("saturdayAM")]
public string saturdayAM { get; set; }
[JsonProperty("saturdayPM")]
public string saturdayPM { get; set; }
}
}
I keep crashing at
userSelection.Add(c.name)
Take a close look at what you are doing
foreach (var addedUser in userSelection.ToArray())
{
if (!addedUser.Contains(c.name))
{
userSelection.Add(c.name);
}
}
You are adding to userSelection in the userSelection loop
The test is on !addedUser.Contains
You should not even be able to do that but I think the ToArrray() is letting it happen
So you add Sally
Then then Mark
Then you add Mark again because in the loop Mark != Sally
You are not using List<String> managerNames = new List<String>();
private void findManagerForSelectedDate(String dateSelected)
{
dateSelected = dateTimePicker1.Value.ToShortDateString();
You pass in dateSelected, then overright with dateTimePicker1, and then you don't even use it
Most of you code makes very little sense to me
I am building a parser for a custom pipe delimited file format and I am finding my code to be very bulky, could someone suggest better methods of parsing this data?
The file's data is broken down by a line delimited by a pipe (|), each line starts with a record type, followed by an ID, followed by different number of columns after.
Ex:
CDI|11111|OTHERDATA|somemore|other
CEX001|123131|DATA|data
CCC|123131|DATA|data1|data2|data3|data4|data5|data6
. I am splitting by pipe, then grabbing the first two columns, and then using a switch checking the first line and calling a function that will parse the remaining into an object purpose built for that record type. I would really like a more elegant method.
public Dictionary<string, DataRecord> Parse()
{
var data = new Dictionary<string, DataRecord>();
var rawDataDict = new Dictionary<string, List<List<string>>>();
foreach (var line in File.ReadLines(_path))
{
var split = line.Split('|');
var Id = split[1];
if (!rawDataDict.ContainsKey(Id))
{
rawDataDict.Add(Id, new List<List<string>> {split.ToList()});
}
else
{
rawDataDict[Id].Add(split.ToList());
}
}
rawDataDict.ToList().ForEach(pair =>
{
var key = pair.Key.ToString();
var values = pair.Value;
foreach (var value in values)
{
var recordType = value[0];
switch (recordType)
{
case "CDI":
var cdiRecord = ParseCdi(value);
if (!data.ContainsKey(key))
{
data.Add(key, new DataRecord
{
Id = key, CdiRecords = new List<CdiRecord>() { cdiRecord }
});
}
else
{
data[key].CdiRecords.Add(cdiRecord);
}
break;
case "CEX015":
var cexRecord = ParseCex(value);
if (!data.ContainsKey(key))
{
data.Add(key, new DataRecord
{
Id = key,
CexRecords = new List<Cex015Record>() { cexRecord }
});
}
else
{
data[key].CexRecords.Add(cexRecord);
}
break;
case "CPH":
CphRecord cphRecord = ParseCph(value);
if (!data.ContainsKey(key))
{
data.Add(key, new DataRecord
{
Id = key,
CphRecords = new List<CphRecord>() { cphRecord }
});
}
else
{
data[key].CphRecords.Add(cphRecord);
}
break;
}
}
});
return data;
}
Try out FileHelper, here is your exact example - http://www.filehelpers.net/example/QuickStart/ReadFileDelimited/
Given you're data of
CDI|11111|OTHERDATA|Datas
CEX001|123131|DATA
CCC|123131
You could create a class to model this to allow FileHelpers to parse the delimited file:
[DelimitedRecord("|")]
public class Record
{
public string Type { get; set; }
public string[] Fields { get; set; }
}
Then we could allow FileHelpers to parse in to this object type:
var engine = new FileHelperEngine<Record>();
var records = engine.ReadFile("Input.txt");
After we've got all the records loaded in to Record objects we can use a bit of linq to pull them in to their given types
var cdis = records.Where(x => x.Type == "CDI")
.Select(x => new Cdi(x.Fields[0], x.Fields[1], x.Fields[2])
.ToArray();
var cexs = records.Where(x => x.Type == "CEX001")
.Select(x => new Cex(x.Fields[0], x.Fields[1)
.ToArray();
var cccs = records.Where(x => x.Type == "CCC")
.Select(x => new Ccc(x.Fields[0])
.ToArray();
You could also simplify the above using something like AutoMapper - http://automapper.org/
Alternatively you could use ConditionalRecord attributes which will only parse certain lines if they match a given criteria. This will however be slower the more record types you have but you're code will be cleaner and FileHelpers will be doing most of the heavy lifting:
[DelimitedRecord("|")]
[ConditionalRecord(RecordCondition.IncludeIfMatchRegex, "^CDI")]
public class Cdi
{
public string Type { get; set; }
public int Number { get; set; }
public string Data1 { get; set; }
public string Data2 { get; set; }
public string Data3 { get; set; }
}
[DelimitedRecord("|")]
[ConditionalRecord(RecordCondition.IncludeIfMatchRegex, "^CEX001")]
public class Cex001
{
public string Type { get; set; }
public int Number { get; set; }
public string Data1 { get; set; }
}
[DelimitedRecord("|")]
[ConditionalRecord(RecordCondition.IncludeIfMatchRegex, "^CCC")]
public class Ccc
{
public string Type { get; set; }
public int Number { get; set; }
}
var input =
#"CDI|11111|Data1|Data2|Data3
CEX001|123131|Data1
CCC|123131";
var CdiEngine = new FileHelperEngine<Cdi>();
var cdis = CdiEngine.ReadString(input);
var cexEngine = new FileHelperEngine<Cex001>();
var cexs = cexEngine.ReadString(input);
var cccEngine = new FileHelperEngine<Ccc>();
var cccs = cccEngine.ReadString(input);
Your first loop isn't really doing anything other than organizing your data differently. You should be able to eliminate it and use the data as it is from the file. Something like this should give you what you want:
foreach (var line in File.ReadLines(_path))
{
var split = line.Split('|');
var key = split[1];
var value = split;
var recordType = value[0];
switch (recordType)
{
case "CDI":
var cdiRecord = ParseCdi(value.ToList());
if (!data.ContainsKey(key))
{
data.Add(key, new DataRecord
{
Id = key, CdiRecords = new List<CdiRecord>() { cdiRecord }
});
}
else
{
data[key].CdiRecords.Add(cdiRecord);
}
break;
case "CEX015":
var cexRecord = ParseCex(value.ToList());
if (!data.ContainsKey(key))
{
data.Add(key, new DataRecord
{
Id = key,
CexRecords = new List<Cex015Record>() { cexRecord }
});
}
else
{
data[key].CexRecords.Add(cexRecord);
}
break;
case "CPH":
CphRecord cphRecord = ParseCph(value.ToList());
if (!data.ContainsKey(key))
{
data.Add(key, new DataRecord
{
Id = key,
CphRecords = new List<CphRecord>() { cphRecord }
});
}
else
{
data[key].CphRecords.Add(cphRecord);
}
break;
}
};
Caveat: This is just put together here and hasn't been properly checked for syntax.