1

HTML テキストを解析し、空の段落をトリミング (または削除) する次のコードがあります。.stripString オブジェクトの場合と同様です。

doc = Nokogiri::HTML::DocumentFragment.parse(html)

# repetition that I want to collapse
doc.css('p').each do |p|
  if all_children_are_blank?(p)
    p.remove
  else
    break
  end
end

# repetition that I want to collapse
doc.css('p').reverse_each do |p|
  if all_children_are_blank?(p)
    p.remove
  else
    break
  end
end

doc.to_s.strip

コメントでラベルを付けたコードが重複するのを防ぎ、コード再利用の原則に従うより洗練された方法はありますか?

これが私が思いついたものですが、まだ満足していません。もっと良いものがあるかどうかを確認したかったのです。

doc = Nokogiri::HTML::DocumentFragment.parse(html)

doc.css('p').each do |p|
  if stop(p) then break end
end

doc.css('p').reverse_each do |p|
  if stop(p) then break end
end

doc.to_s.strip

def self.stop(p)
  if all_children_are_blank?(p)
    p.remove
    false
  else
    true
  end
end
4

3 に答える 3

1

どうですか:

[*doc.css('p'), *doc.css('p').reverse].each do |p|
  if stop(p) then break end
end

この場合、splat演算子( "*")は、両方のリストを1つの配列に展開し、要素を昇順、降順で展開します。次に、グループ全体を繰り返し処理します。


break編集:ステートメントがすべての最後にスキップされるため、これは正しく機能しません。したがって、これを行う適切な方法であるIMHOは、ブロックを変数に割り当てることです。stopとにかくコードの重複を排除しているので、関数を排除したほうがよいでしょう。

remover = lambda do |p|
  if all_children_are_blank? p
    p.remove
  else
    break
  end
end

doc.css('p').to_a.each(&remover).reverse_each(&remover)

お役に立てれば。

于 2012-12-06T23:27:54.457 に答える
1

あなたが探しているものを理解したら、空白のp要素を削除するために、見ている要素を反復処理するより簡単な方法が必要です。

これは、まったく異なることをせずに、書いたものを折りたたむ簡単な方法です。

doc.tap do |d|
  [:each, :reverse_each].each do |sym|
    d.css("p").public_send(sym) do |p|
      if blank_children?(p)
        p.remove
      else
        break
      end
    end
  end
end.to_s.strip

私はこれをテストしていないので、少し調整する必要があるかもしれません. これが製品コードである場合は、わかりやすくするために、おそらく 1 つまたは複数のメソッド呼び出しに分解します。

于 2012-12-06T22:19:08.517 に答える