Reputation: 1194
i am using LINQ and HtmlAgilitypack to create a datatable out of an HTML. the following gets the html table headers and constructs the datatable columns:
var nodes = htmlDoc.DocumentNode.SelectNodes("//table[@class='ps-sellers-table crts']/tr");
nodes[0].Elements("th")
.Skip(0)
.Select(th => th.InnerText
.Trim())
.ToList()
.ForEach(header => dt.Columns.Add(header));
so far its working perfectly except i need some customization.
this select statement will do the 2 things above:
switch (header)
{
case ("id") : dt.Columns.Add(header,typeof(int)); break;
case ("name") : dt.Columns.Add(header,typeof(string)); break;
case ("price") : dt.Columns.Add(header,typeof(decimal)); break;
case ("shipping") : dt.Columns.Add(header,typeof(decimal)); break;
default : //skip the column and dont add it
}
however i am really new to LINQ and C#, and i want to implement the above switch case inside the foreach in the first snippet, i know i should use ternary operator
, but i am not sure about the sytax.
Upvotes: 2
Views: 2328
Reputation: 43596
You could just add the switch to the foreach, not sure why you have to use the ternary operator
.ToList().ForEach(header =>
{
switch (header)
{
case ("id"): dt.Columns.Add(header, typeof(int)); break;
case ("name"): dt.Columns.Add(header, typeof(string)); break;
case ("price"): dt.Columns.Add(header, typeof(decimal)); break;
case ("shipping"): dt.Columns.Add(header, typeof(decimal)); break;
default: break; //skip the column and dont add it
}
});
Upvotes: 1
Reputation: 564413
I would wrap the switch into a method, and then call the method from within your select statement.
My version would look like:
var nodes = htmlDoc.DocumentNode.SelectNodes("//table[@class='ps-sellers-table crts']/tr");
nodes[0].Elements("th")
.Select(th => th.InnerText.Trim());
foreach(var node in nodes)
AddColumnToDataTable(node, dt);
Note that there's no need to Skip(0)
, and calling ToList()
just to use List<T>.ForEach
reduces readability and adds overhead. I personally prefer just using a normal foreach
.
That being said, your method could be refactored into using a Dictionary<string, Type>
instead. If you add this to your class:
Dictionary<string, Type> typeLookup;
// In your constructor:
public YourClass()
{
typeLookup.Add("id", typeof(int));
typeLookup.Add("name", typeof(string));
typeLookup.Add("price", typeof(decimal));
typeLookup.Add("shipping", typeof(decimal));
}
You could then write your method as:
void AddColumnToDataTable(string columnName, DataTable table)
{
table.Columns.Add(columnName, typeLookup[columnName]);
}
Upvotes: 5