Czy istnieje lepszy sposób na sprawdzenie zera lub długości == 0 ciągu w Rubim?

169

Czy jest lepszy sposób niż poniższy, aby sprawdzić, czy łańcuch jest zerowy LUB ma długość 0 w Rubim?

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

W C # jest poręczny

string.IsNullOrEmpty(myString)

Coś podobnego do tego w Rubim?

Jim Fiorato
źródło
16
Nie ma sensu mieć takiej instrukcji if: „if (condition) then true else false”. Sam warunek ma taką samą prawdziwość jak stwierdzenie „jeśli”.
KaptajnKold
my_string || my_string.length == 0podniesie NoMethodErrorjeśli my_stringjest zero. Myślę, że miałeś na myśli:my_string.nil? || my_string.length == 0
Naveed
1
Powinno być!my_string || my_string.length == 0
levsa

Odpowiedzi:

224

Kiedy nie martwię się o wydajność, często używam tego:

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

Oczywiście istnieją różne warianty ...

if my_string.to_s.strip.length == 0
  # It's nil, empty, or just whitespace
end
Ezran
źródło
2
Odmiana przy użyciu stripmoże być dość nieefektywna.
Marc-André Lafortune
10
innym interesującym sposobem jest my_string.to_s.empty?
Ricardo Pessoa
Dla większości ludzi pierwsza opcja będzie całkowicie akceptowalna i dobrze się czyta.
amrcus,
68

Jeśli chcesz wymagać ActiveSupport, możesz po prostu użyć #blank?metody, która jest zdefiniowana zarówno dla NilClass, jak i String.

Avdi
źródło
15
Zauważ, że łańcuch zawierający tylko białe znaki jest nadal uważany za pusty. Więc "" .blank? jest prawdziwy.
Grant Hutchins
2
Ponadto wartości logiczne false, {} i [] są uważane za puste. To znaczy {} .blank ?, [] .blank ?, false.blank? wszystkie oceniają jako prawdziwe.
ShaharZ
64

Lubię to robić w następujący sposób (w środowisku innym niż Rails / ActiveSupport):

variable.to_s.empty?

to działa, ponieważ:

nil.to_s == ""
"".to_s == ""
Vinay Sahni
źródło
3
Dobre wyjaśnienie, dlaczego string.to_s.empty?działa zarówno w przypadku, jak nili "".
georger
31

Alternatywą dla propozycji jcoby'ego byłoby:

class NilClass
  def nil_or_empty?
    true
  end
end

class String
  def nil_or_empty?
    empty?
  end
end
Rômulo Ceccon
źródło
10
Ale… ale… Ruby core już to implementuje. nil.to_s => "", więc możesz powiedzieć thing.to_s == ""
DigitalRoss,
1
@DigitalRoss Pozwala to uniknąć konwersji ciągów, która może, ale nie musi, być niewielkim problemem z wydajnością.
Vortico,
30

Jak powiedziano wcześniej, Railsy (ActiveSupport) mają poręczny blank? metoda i jest zaimplementowana w następujący sposób:

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

Całkiem łatwo dodać do dowolnego projektu opartego na Ruby.

Piękno tego rozwiązania polega na tym, że działa auto-magicznie nie tylko w przypadku ciągów, ale także w przypadku tablic i innych typów.

Honza
źródło
15

variable.blank? zrobię to. Zwraca prawdę, jeśli łańcuch jest pusty lub jeśli łańcuch jest zerowy.

Satya Kalluri
źródło
12
Właściwie jest to tylko przedłużenie szyn, a nie czysty rubin. Ale jeśli używasz szyn, jest to bardzo przydatne!
James P McGrath
13

nil?można pominąć w kontekstach logicznych. Ogólnie można użyć tego do replikacji kodu C #:

return my_string.nil? || my_string.empty?
Konrad Rudolph
źródło
7

Przede wszystkim uważaj na tę metodę:

Jak mówi Jesse Ezel :

Brad Abrams

„Ta metoda może wydawać się wygodna, ale przez większość czasu stwierdzałem, że sytuacja ta wynika z prób ukrywania głębszych błędów.

Twój kod powinien być zgodny z określonym protokołem dotyczącym używania łańcuchów i powinieneś zrozumieć użycie tego protokołu w kodzie biblioteki oraz w kodzie, z którym pracujesz.

Protokół NullOrEmpty to zwykle szybka naprawa (więc prawdziwy problem nadal tkwi gdzie indziej, a masz dwa używane protokoły) lub jest to brak wiedzy na temat konkretnego protokołu podczas wdrażania nowego kodu (i znowu, naprawdę powinieneś wiedzieć, co zwracane wartości to). ”

A jeśli załatasz klasę String ... upewnij się, że NilClass też nie został poprawiony !

class NilClass
    def empty?; true; end
end
VonC
źródło
5

Każda klasa ma nil?metodę:

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

A stringi mają empty?metodę:

if a_string.empty?
    # the string is empty
}

Pamiętaj, że ciąg nie jest równy, nilgdy jest pusty, więc użyj empty?metody, aby sprawdzić, czy ciąg jest pusty.

Jeremy Ruten
źródło
4

Inną opcją jest konwersja zera na pusty wynik w locie:

(my_string||'').empty?

mahemoff
źródło
2

Konrad Rudolph ma właściwą odpowiedź.

Jeśli naprawdę cię to wkurza, małpuj popraw klasę String lub dodaj ją do wybranej klasy / modułu. Naprawianie łatek podstawowych obiektów naprawdę nie jest dobrą praktyką, chyba że masz naprawdę ważny powód.

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

Wtedy możesz to zrobić String.nilorempty? mystring

jcoby
źródło
2

Sprawdź puste ciągi w zwykłym języku Ruby, unikając wyjątków NameError

Jest tutaj kilka dobrych odpowiedzi, ale nie potrzebujesz ActiveSupport ani małpiego poprawiania, aby rozwiązać typowy przypadek użycia tutaj. Na przykład:

my_string.to_s.empty? if defined? my_string

To „zrobi dobrze”, jeśli my_string ma wartość nil lub jest pustym ciągiem, ale nie zgłosi wyjątku NameError, jeśli my_string nie jest zdefiniowany. Jest to generalnie lepsze niż bardziej wymyślone:

my_string.to_s.empty? rescue NameError

lub jest bardziej rozwlekły, ponieważ wyjątki powinny być naprawdę zapisywane dla rzeczy, których się nie spodziewasz. W tym przypadku, chociaż może to być powszechny błąd, niezdefiniowana zmienna nie jest tak naprawdę wyjątkową okolicznością, więc należy ją odpowiednio traktować.

Twój przebieg może się różnić.

Todd A. Jacobs
źródło
1

Czy próbowałeś doprecyzować?

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?
RichOrElse
źródło
1

Jeśli używasz szyn, możesz użyć #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)

Czyli odwrotnie, aby sprawdzić użycie długości zerowej lub zerowej !present?

!(nil.present?)  # ==> true
!(''.present?)    # ==> true
!('  '.present?)  # ==> true
!([].present?)    # ==> true
!(false.present?) # ==> true
Dhivya Dandapani
źródło
0

W szynach możesz spróbować #blank?.

Ostrzeżenie: da ci pozytywy, gdy ciąg składa się ze spacji:

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

Chciałem tylko zwrócić na to uwagę. Może odpowiada Twoim potrzebom

UPD. dlaczego w moim kanale pojawiają się stare pytania? Przepraszamy za nekroposty.

Nondv
źródło
0

Dla golfistów kodu:

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

Lub jeśli nie jesteś golfistą (wymagana wersja Ruby 2.3 lub nowsza):

if my_string&.size&.positive?
  # nonzero? also works
  p 'non-empty string'
else
  p 'nil or empty string'
end
snipsnipsnip
źródło