【问题标题】:LINQ Where SyntaxLINQ 语法
【发布时间】:2013-03-06 04:09:20
【问题描述】:

我有以下 LINQ 在 HTMLAgilityPack 的帮助下从 html <tr> 标签填充数据表,每个标签都有一个属性,如果属性值为“rating-”,我需要忽略该标签的 innertext科尔”。

nodes.Skip(1)
.Select(
tr => tr.Elements("td").
    Select(td => td.InnerText.
        Where(td.Attributes[0].Value != "rating-col")).
        ToArray()).
        ToList().
        ForEach(row => dt.Rows.Add(row));

没有 Where 子句一切正常,我在 Where 子句中做错了什么?

【问题讨论】:

  • 如果可以,请编辑并添加您的异常或错误。
  • 不清楚您是要跳过每一行中的一列,还是跳过表格中的某些行。
  • Where(td=> td.Attributes[0].Value != "rating-col"))
  • @DotNetDreamer:OP 不能使用td。它是一个内部Where,将重新定义td
  • "每个标签都有一个属性..." 这似乎是一个非常脆弱的测试:您依赖于属性的确切数量/位置来使您的逻辑工作。为什么不使用特定的命名属性,而直接定位它呢?如果这不在您的控制范围内,那么您可能应该在所有属性中查找“rating-col”(如果需要这样做),以防添加其他属性。

标签: c# linq html-agility-pack


【解决方案1】:

Where(td.Attributes[0].Value != "rating-col")) 里面应该有一个 lambda ...例如:

Where(c => c.Attributes[0].Value != "rating-col"))

【讨论】:

  • 它也需要在select之前。
  • @RaymondChen 做到了 ;)
  • @user1590636 希望你明白为什么。
  • @RaymondChen 起初我没有,但现在我做到了:D
【解决方案2】:

看起来您缺少一个 lambda,并且其中一个 Select 出现了故障。另外,这里没有ToList()ForEach() 的理由。您的ToList() 电话使事情变慢并迫使您使用更多内存。您需要它的唯一原因是获得ForEach() 扩展名,这并不能真正为您节省任何通过正常的foreach 循环。另外,虽然我不是该领域的专家,但我知道ForEach() 扩展的功能风格很差,因为它几乎假定您正在造成副作用(一个很大的功能禁忌)。由于 linq 深受函数式编程范式的启发,因此我尝试关注这些事情。

foreach (var row in nodes.Skip(1)
     .Select(tr => tr.Elements("td")
         .Where(td => td.Attributes[0].Value != "rating-col")
         .Select(td => td.InnerText)
         .ToArray()))
{
    dt.Rows.Add(row);
}

【讨论】:

  • 这个功能会更快吗? :D
  • 应该是。它使您不必循环遍历元素两次。您当前的代码必须循环一次以创建列表,并在创建列表后再次循环以将这些元素复制到数据表(加上额外的内存来保存临时列表)。这避免了这一切。它只循环一次,并且一次只保留内存中的一个行数组。它还节省了为不会产生最终结果的列引用 InnerText 属性的工作。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多