2013-09-27 4 views
2

Я хочу получить delete_if, чтобы удалить пустые строки из массива. В приведенном ниже решении массив все еще содержит много пустых строк.Как удалить пустые строки в массиве

products = my_text.split(/\t+/) 
products.delete_if {|element| element == " " || "" || element.nil?} 

Есть что-то не хватает?

+3

'products.reject! {| s | s.strip.empty? || s.nil? } ' – oldergod

+5

Вы хотите изменить это на' products.reject! {| продукт | product.nil? || product.strip.empty? } 'в противном случае вы попробуете' strip' 'nil' – Momer

+0

@Momer вы так правы, спасибо! – oldergod

ответ

8

Проблема с кодом объясняется Ed S.
В противном случае, вы можете сделать

products.reject! { |s| s.nil? || s.strip.empty? } 

Почему вы должны проверить nil? первый? Давайте проверим несколько строк.

nil.strip 
# NoMethodError: undefined method `strip' for nil:NilClass 
" ".strip 
# => "" 

Теперь, с другим порядком, что делает код, если объект является строкой, а затем, если он равен нулю.

" ".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 является правдивым (то есть не nil, ни false), b никогда не будет называться.
Сначала вы тестируете, если строка nil; если это так, вам не нужно проверять правильную часть (чтобы вы не получили неопределенную ошибку метода), и объект будет удален из вашего списка продуктов.

+0

С Ruby 2.3 вы можете использовать [безопасный навигационный оператор] (http://mitrev.net/ruby/2015/11/13/the-operator-in-ruby/), чтобы избежать проверки на 'nil':' products.reject! {| s | s & .strip & .empty? } ' –

2

Ну это не так:

element == " " || "" || element.nil? 

Должно быть

products = products.delete_if {|element| element == " " || element == "" || element.nil? 

Обратите внимание, что вы имели || "" || там. Вы не сравнивали element с "", вы тестировали «правду» "" (что оценивает true, ответив на вашу пустую проверку строки).

Это, конечно, предполагает, что ваше определение «пустой строки» равно либо нулю, либо " ", либо "". Как насчет

" " 

или даже

"   " 

?

+0

Это, безусловно, привело меня на правильный путь! Но теперь, когда я его отлаживаю, эта строка кода выполняется несколько раз, и к моменту ее выполнения она удаляет весь массив. По какой-то причине логическое значение имеет значение true, поскольку каждая строка имеет по крайней мере одно пространство в нем. –

+0

Да, поэтому вы ожидали моей проблемы с вашим ответом. –

+0

@AdamBronfin: Сравнение строк не работает. Это не 'contains', это сравнение со значением, не более. Используйте предложение @ oldergod в комментариях. –

Смежные вопросы