delete_if
配列から空の文字列を削除したい。以下の解決策では、配列にはまだ多くの空の文字列が含まれています。
products = my_text.split(/\t+/)
products.delete_if {|element| element == " " || "" || element.nil?}
何か足りないものはありますか?
あなたのコードの問題は Ed S によって説明されて
います。
products.reject! { |s| s.nil? || s.strip.empty? }
なぜnil?
最初にテストする必要があるのですか?数行確認してみましょう。
nil.strip
# NoMethodError: undefined method `strip' for nil:NilClass
" ".strip
# => ""
さて、別の順序で、オブジェクトが文字列の場合と nil の場合のコードの動作を示します。
" ".strip || " ".nil?
# => ""
nil.strip || nil.nil?
# NoMethodError: undefined method `strip' for nil:NilClass
# Oh you don't want that to happen, do you?
strip.empty?
これは、オブジェクトが のときに呼び出したくないことを意味しますnil
。
ご存知のように、 を持っているときa || b
、 a が true の場合 (つまり、nil
nor でない場合false
)b
は決して呼び出されません。文字列が;
かどうかを最初にテストします。nil
そうであれば、正しい部分をチェックする必要はなく (したがって、未定義のメソッド エラーが発生することはありません)、オブジェクトは製品リストから削除されます。
これは間違っています:
element == " " || "" || element.nil?
する必要があります
products = products.delete_if {|element| element == " " || element == "" || element.nil?
そこに があったことに注意してください|| "" ||
。と比較element
していたのではなく""
、の「真実性」をテストしていました(ところで、空の文字列チェックを台無しに""
評価します)。true
もちろん、これは「空の文字列」の定義が nil 、" "
、または""
. どうですか
" "
あるいは
" "
?