C#LINQ三元运算符作为switchcase里面的一个foreach
我使用LINQ和HtmlAgilitypack来创建一个HTML外的数据表。 下面获取HTML表格的标题和构建数据表列:C#LINQ三元运算符作为switchcase里面的一个foreach
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));
到目前为止它的工作完全不同的,我需要一些定制。
- 选择要添加的列。
- 并指定列类型。
这个SELECT语句会做两件事情上面:
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
}
但是我真的很新的LINQ和C#,我想实现在foreach内部的上述开关的情况下在第一个片段,我知道我应该使用ternary operator
,但我不确定这个sytax。
我会将开关包装到一个方法中,然后从您的select语句中调用该方法。
我的版本会是什么样子:
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);
注意,有没有必要Skip(0)
,并呼吁ToList()
只是使用降低可读性和增加开销。我个人更喜欢使用正常的foreach
。
这就是说,你的方法可以被重构为使用Dictionary<string, Type>
来代替。如果您添加到您的类:
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));
}
然后,您可以写你的方法:
void AddColumnToDataTable(string columnName, DataTable table)
{
table.Columns.Add(columnName, typeLookup[columnName]);
}
你可以直接在'IEnumerable'上使用'Aggregate(dt,(table,header)=> dt.Columns.Add(header))'来避免'ToList'调用的混淆 – 2013-03-05 21:24:37
@ just.another.programmer I无论如何都避免了“ToList”调用。一般来说,我喜欢避免执行副作用的LINQ语句 - 在LINQ查询中对任何方法(如“添加”)的任何调用都会导致不良习惯的尖叫......也就是说,如果您想要使用“Aggregate”这样做 - 一个简单的'选择'也可以工作... – 2013-03-05 21:27:26
只是一个小问题,关于忽略使用where子句的列,以下是好吗? 'nodes [0] .Elements(“th”)。Select(th => th.InnerText.Trim())。where(th => th!=“somecolumn”);' – user1590636 2013-03-05 22:22:59
你可以切换只需添加到在foreach,不知道为什么你必须使用三元运算
.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
}
});
为什么不写一个使用开关块并调用方法的方法呢? – 2013-03-05 20:57:47
我同意torrential,过度滥用三元运算符使代码混乱,几乎不可读。包含逻辑的方法更具可读性(如果公开,则可测试)。我个人只使用布尔运算符作为三元运算符。 – 2013-03-05 20:59:22
它看起来像是在列名和类型之间有一个简单的映射。为什么不使用“字典”? –
2013-03-05 21:03:57