Чи є кращий спосіб перевірити нуль або довжину == 0 рядка в Ruby?


169

Чи є кращий спосіб, ніж наступний, щоб перевірити, чи є рядок нульовим АБО чи має в Ruby довжину 0?

if !my_string || my_string.length == 0
  return true
else
  return false
end

У C # там зручно

string.IsNullOrEmpty(myString)

Щось подібне до того, що у Рубі?


16
Зайвим є вислів if, як це: "if (умова), то true else false". Сама умова має таку ж правдивість, як твердження if.
KaptajnKold

my_string || my_string.length == 0підніме а, NoMethodErrorякщо my_stringнуль. Я думаю, ти мав на увазі:my_string.nil? || my_string.length == 0
Naveed

1
Чи має бути!my_string || my_string.length == 0
levsa

Відповіді:


224

Коли я не переживаю за продуктивність, я часто користуюся цим:

if my_string.to_s == ''
  # It's nil or empty
end

Існують різні варіанти, звичайно ...

if my_string.to_s.strip.length == 0
  # It's nil, empty, or just whitespace
end

2
Використання варіацій stripможе бути досить неефективним.
Марк-Андре Лафортун

10
Ще один цікавий спосіб - my_string.to_s.empty?
Рікардо Пессоа

Для більшості людей перший варіант буде цілком прийнятним і добре читається.
amrcus

68

Якщо ви бажаєте вимагати ActiveSupport, ви можете просто скористатися #blank?методом, визначеним як для NilClass, так і для String.


15
Зауважте, що рядок, що містить лише пробіл, все ще вважається порожнім. Так "" .пусто? правда.
Грант Хатчінз

2
Також булеві значення false {} і [] вважаються порожніми. Тобто {} .blank ?, [] .blank ?, false.blank? всі оцінюють до правдивого.
ShaharZ

64

Мені подобається це робити так (у середовищі, що не належить до Rails / ActiveSupport):

variable.to_s.empty?

це працює, тому що:

nil.to_s == ""
"".to_s == ""

3
Гарне пояснення, чому string.to_s.empty?працює і для, nilі для "".
Джорджер

31

Альтернативою пропозиції jcoby буде:

class NilClass
  def nil_or_empty?
    true
  end
end

class String
  def nil_or_empty?
    empty?
  end
end

10
Але .. але .. Основна бібліотека ruby ​​це вже реалізує. nil.to_s => "", так що ви можете сказати thing.to_s == ""
DigitalRoss

1
@DigitalRoss Це дозволяє уникнути конверсії рядків, яка може бути, а може бути, незначною проблемою продуктивності.
Vortico

30

Як було сказано тут, перш ніж у Rails (ActiveSupport) є зручна заготовка? і він реалізується так:

class Object
  def blank?
    respond_to?(:empty?) ? empty? : !self
  end
end

Досить легко додати до будь-якого проекту, що базується на рубіні.

Краса цього рішення полягає в тому, що воно працює автомагічно не лише для Strings, але і для масивів та інших типів.


15

varia.blank? зробимо це. Він повертає true, якщо рядок порожній або якщо рядок є нульовою.


12
Власне, це рельси лише розширення, а не чистий рубін. Але якщо ви використовуєте рейки, це дуже зручно!
Джеймс П МакГрат

13

nil?може бути опущено в булевих контекстах. Як правило, ви можете використовувати це для копіювання коду C #:

return my_string.nil? || my_string.empty?

7

Перш за все, остерігайтеся цього методу:

Як каже Джессі Езел :

Бред Абрамс

"Метод може здатися зручним, але більшу частину часу я виявляв, що така ситуація виникає при спробі приховати глибші помилки.

Ваш код повинен дотримуватися певного протоколу щодо використання рядків, і ви повинні розуміти використання протоколу в бібліотечному коді та в коді, з яким ви працюєте.

Протокол NullOrEmpty - це, як правило, швидке виправлення (тому справжня проблема все-таки десь інша, і у вас є два протоколи у використанні) або це недостатній досвід у конкретному протоколі при впровадженні нового коду (і знову ж таки, ви дійсно повинні знати, що ваші повернені значення). "

І якщо ви виправляєте клас String ... будьте впевнені, що NilClass теж не був патчем !

class NilClass
    def empty?; true; end
end

5

У кожному класі є nil?метод:

if a_variable.nil?
    # the variable has a nil value
end

І рядки мають empty?метод:

if a_string.empty?
    # the string is empty
}

Пам'ятайте, що рядок не дорівнює, nilколи вона порожня, тому використовуйте empty?метод, щоб перевірити, чи рядок порожній.


4

Іншим варіантом є перетворення нуля в порожній результат на ходу:

(my_string||'').empty?


2

Конрад Рудольф має правильну відповідь.

Якщо він насправді вас помиляє, мавпа виправляє клас String або додає його до класу / модуля на ваш вибір. Це дійсно не є хорошою практикою мавпочки виправляти основні об'єкти, якщо у вас немає поважної причини.

class String
  def self.nilorempty?(string)
    string.nil? || string.empty?
  end
end

Тоді ви можете зробити String.nilorempty? mystring


2

Перевірте наявність порожніх рядків у звичайній рубіні, уникаючи винятків NameError

Тут є кілька хороших відповідей, але вам не потрібен ActiveSupport або патч з мавпами для вирішення загального випадку тут. Наприклад:

my_string.to_s.empty? if defined? my_string

Це "зробить правильно", якщо my_string є нульовим або порожнім рядком, але не призведе до винятку NameError, якщо my_string не визначено. Це, як правило, краще для більш надуманих:

my_string.to_s.empty? rescue NameError

або його більш багатослівний ілк, оскільки справді слід зберігати винятки для речей, яких ви не очікуєте. У цьому випадку, хоча це може бути звичайна помилка, невизначена змінна насправді не є винятковою обставиною, тому з нею слід поводитися відповідно.

Ваш пробіг може відрізнятися.


1

Ви пробували вдосконалення?

module Nothingness
  refine String do
    alias_method :nothing?, :empty?
  end

  refine NilClass do
    alias_method :nothing?, :nil?
  end
end

using Nothingness

return my_string.nothing?

1

Якщо ви використовуєте рейки, ви можете використовувати #present?

require 'rails'

nil.present?  # ==> false (Works on nil)
''.present?    # ==> false (Works on strings)
'  '.present?  # ==> false (Works on blank strings)
[].present?    # ==> false(Works on arrays)
false.present? # ==> false (Works on boolean)

Отже, навпаки, перевірити наявність нульової або нульової довжини !present?

!(nil.present?)  # ==> true
!(''.present?)    # ==> true
!('  '.present?)  # ==> true
!([].present?)    # ==> true
!(false.present?) # ==> true

0

У рейках можна спробувати #blank?.

Попередження: він дасть позитивні результати, коли рядок складається з пробілів:

nil.blank? # ==> true
''.blank? # ==> true
'  '.blank? # ==> true
'false'.blank? # ==> false

Просто хотів це вказати. Можливо, це відповідає вашим потребам

UPD. чому я отримую старі запитання у своєму каналі? Вибачте за некропостинг.


0

Для кодових гольфістів:

if my_string=~/./
  p 'non-empty string'
else
  p 'nil or empty string'
end

Або якщо ви не гольфіст (потрібен рубін 2.3 або пізнішої версії):

if my_string&.size&.positive?
  # nonzero? also works
  p 'non-empty string'
else
  p 'nil or empty string'
end
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.