Лично я предпочитаю if elif else
сопоставлению с шаблоном, когда у вас нет структуры данных для декомпозиции (она просто меньше печатает, а также может помочь различать, когда структура подвергается декомпозиции, и более простое тестирование случая).
В вашем коде есть странные вещи.Активный шаблон здесь не очень полезен по двум причинам: во-первых, его область действия ограничена removeNodes, поэтому он используется только один раз.Я расскажу о вторых проблемах позже, но сначала я покажу, как бы я это написал, исключив Active Pattern и, по крайней мере, для меня, сделав побочные эффекты более очевидными (выделив код, который проверяет, должен ли узел бытьудалено из кода, который выполняет удаление):
let shouldRemoveNode (node : HtmlNode) =
if node.Name.ToLower() = "script" then true
elif node.NodeType = HtmlNodeType.Comment then true
else match node.SelectNodes("*[@style[contains(.,'visibility:hidden')]]") with
| null -> false
| x -> Seq.length x > 0
let removeNode (node: HtmlNode) =
if shouldRemoveNode(node) then node.Remove() else ()
Обратите внимание, что я использую сопоставление с шаблоном в скрытом запросе видимости, поскольку я получаю сопоставление с нулем и связывание с х в противном случае (вместо привязки к хи затем проверяем x с помощью if else
).
Вторая странная вещь в вашем активном шаблоне заключается в том, что вы используете его для преобразования узла в int, но полученная длина не сразу полезна (вам все еще нужно выполнить тест против него).Принимая во внимание, что более мощное использование Активного Паттерна здесь будет состоять в том, чтобы разделить узлы на различные виды (при условии, что это не случайный случай, который может быть первым пунктом).Таким образом, вы могли бы иметь:
//expand to encompass several other kinds of nodes
let (|Script|Comment|Hidden|Other|) (node : HtmlNode) =
if node.Name.ToLower() = "script" then Script
elif node.NodeType = HtmlNodeType.Comment then Comment
else match node.SelectNodes("*[@style[contains(.,'visibility:hidden')]]") with
| null -> Other
| x -> if Seq.length x > 0 then Hidden
else Other
let removeNode (node: HtmlNode) =
match node with
| Script | Comment | Hidden -> node.Remove()
| Other -> ()
Редактировать:
@ Паскаль сделал замечание в комментариях, что shouldRemoveNode
может быть далее сжато в одно большое логическое выражение:
let shouldRemoveNode (node : HtmlNode) =
node.Name.ToLower() = "script" ||
node.NodeType = HtmlNodeType.Comment ||
match node.SelectNodes("*[@style[contains(.,'visibility:hidden')]]") with
| null -> false
| x -> Seq.length x > 0