Existe-t-il un meilleur moyen de vérifier Nil ou Length == 0 d'une chaîne en Ruby?

169

Existe-t-il un meilleur moyen que le suivant pour vérifier si une chaîne est nulle OU a une longueur de 0 dans Ruby?

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

En C #, il y a le pratique

string.IsNullOrEmpty(myString)

Quelque chose de similaire à celui de Ruby?

Jim Fiorato
la source
16
Il est redondant d'avoir une instruction if comme celle-ci: "if (condition) then true else false". La condition elle-même a la même véracité que l'énoncé if.
KaptajnKold
my_string || my_string.length == 0lèvera un NoMethodErrorsi my_stringest nul. Je pense que vous vouliez dire:my_string.nil? || my_string.length == 0
Naveed le
1
Devrait-il être!my_string || my_string.length == 0
levsa

Réponses:

224

Quand je ne suis pas inquiet pour les performances, j'utilise souvent ceci:

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

Il existe bien sûr diverses variantes ...

if my_string.to_s.strip.length == 0
  # It's nil, empty, or just whitespace
end
Ezran
la source
2
La variation utilisant strippeut être assez inefficace.
Marc-André Lafortune
10
une autre façon intéressante est my_string.to_s.empty?
Ricardo Pessoa
Pour la plupart des gens, la première option sera tout à fait acceptable et se lit bien.
amrcus
68

Si vous souhaitez avoir besoin d'ActiveSupport, vous pouvez simplement utiliser la #blank?méthode, qui est définie pour NilClass et String.

Avdi
la source
15
Notez qu'une chaîne contenant uniquement des espaces est toujours considérée comme vide. Alors "" .blank? est vrai.
Grant Hutchins
2
De plus, les valeurs booléennes false, {} et [] sont considérées comme vides. Ie {} .blank ?, [] .blank ?, false.blank? tous évaluent à vrai.
ShaharZ
64

J'aime faire cela comme suit (dans un environnement non Rails / ActiveSupport):

variable.to_s.empty?

cela fonctionne parce que:

nil.to_s == ""
"".to_s == ""
Vinay Sahni
la source
3
Une bonne explication pourquoi string.to_s.empty?fonctionne pour les deux nilet "".
georger
31

Une alternative à la proposition de jcoby serait:

class NilClass
  def nil_or_empty?
    true
  end
end

class String
  def nil_or_empty?
    empty?
  end
end
Rômulo Ceccon
la source
10
Mais… mais… La bibliothèque de base ruby ​​l'implémente déjà. nil.to_s => "", pour que vous puissiez dire thing.to_s == ""
DigitalRoss
1
@DigitalRoss Cela évite la conversion de chaîne qui peut ou non être un léger problème de performances.
Vortico
30

Comme il a été dit ici avant que Rails (ActiveSupport) ait un vide pratique ? méthode et il est implémenté comme ceci:

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

Assez facile à ajouter à tout projet basé sur Ruby.

La beauté de cette solution est qu'elle fonctionne automatiquement par magie non seulement pour les chaînes, mais aussi pour les tableaux et autres types.

Honza
la source
15

variable.blank? le fera. Il renvoie true si la chaîne est vide ou si la chaîne est nulle.

Satya Kalluri
la source
12
En fait, il s'agit d'une extension de rails uniquement, pas de rubis pur. Mais si vous utilisez des rails, c'est très pratique!
James P McGrath
13

nil?peut être omis dans les contextes booléens. En règle générale, vous pouvez l'utiliser pour répliquer le code C #:

return my_string.nil? || my_string.empty?
Konrad Rudolph
la source
7

Tout d'abord, méfiez-vous de cette méthode:

Comme le dit Jesse Ezel :

Brad Abrams

«La méthode peut sembler pratique, mais la plupart du temps, j'ai trouvé que cette situation venait de la tentative de dissimuler des bogues plus profonds.

Votre code doit s'en tenir à un protocole particulier sur l'utilisation des chaînes, et vous devez comprendre l'utilisation du protocole dans le code de la bibliothèque et dans le code avec lequel vous travaillez.

Le protocole NullOrEmpty est généralement une solution rapide (donc le vrai problème est toujours ailleurs, et vous avez deux protocoles en cours d'utilisation) ou il s'agit d'un manque d'expertise dans un protocole particulier lors de la mise en œuvre d'un nouveau code (et encore une fois, vous devez vraiment savoir ce que vos valeurs de retour sont). "

Et si vous corrigez la classe String ... assurez-vous que NilClass n'a pas été corrigée non plus !

class NilClass
    def empty?; true; end
end
VonC
la source
5

Chaque classe a une nil?méthode:

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

Et les chaînes ont la empty?méthode:

if a_string.empty?
    # the string is empty
}

N'oubliez pas qu'une chaîne n'est pas égale nillorsqu'elle est vide, utilisez donc la empty?méthode pour vérifier si une chaîne est vide.

Jeremy Ruten
la source
4

Une autre option consiste à convertir nil en résultat vide à la volée:

(my_string||'').empty?

Mahemoff
la source
2

Konrad Rudolph a la bonne réponse.

Si cela vous dérange vraiment, modifiez la classe String ou ajoutez-la à une classe / module de votre choix. Ce n'est vraiment pas une bonne pratique de monkey patcher les objets principaux à moins que vous n'ayez une raison vraiment convaincante.

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

Alors tu peux faire String.nilorempty? mystring

jcoby
la source
2

Rechercher les chaînes vides dans Ruby brut tout en évitant les exceptions NameError

Il y a quelques bonnes réponses ici, mais vous n'avez pas besoin d'ActiveSupport ou de monkey-patching pour traiter le cas d'utilisation courant ici. Par exemple:

my_string.to_s.empty? if defined? my_string

Cela "fera la bonne chose" si ma_chaîne est nulle ou une chaîne vide, mais ne lèvera pas d'exception NameError si ma_chaîne n'est pas définie. Ceci est généralement préférable aux plus artificiels:

my_string.to_s.empty? rescue NameError

ou son acabit plus verbeux, car les exceptions devraient vraiment être enregistrées pour des choses que vous ne vous attendez pas à ce qu'elles se produisent. Dans ce cas, bien qu'il s'agisse d'une erreur courante, une variable non définie n'est pas vraiment une circonstance exceptionnelle, elle doit donc être traitée en conséquence.

Votre kilométrage peut varier.

Todd A. Jacobs
la source
1

Avez-vous essayé les raffinements?

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
la source
1

Si vous utilisez des rails, vous pouvez utiliser #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)

Donc, inversement pour vérifier l'utilisation de longueur nulle ou nulle !present?

!(nil.present?)  # ==> true
!(''.present?)    # ==> true
!('  '.present?)  # ==> true
!([].present?)    # ==> true
!(false.present?) # ==> true
Dhivya Dandapani
la source
0

Dans les rails, vous pouvez essayer #blank?.

Attention: cela vous donnera des points positifs lorsque la chaîne est composée d'espaces:

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

Je voulais juste le souligner. Peut-être que cela répond à vos besoins

UPD. pourquoi ai-je de vieilles questions dans mon flux? Désolé pour le nécropostage.

Nondv
la source
0

Pour les golfeurs de code:

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

Ou si vous n'êtes pas un golfeur (nécessite ruby ​​2.3 ou version ultérieure):

if my_string&.size&.positive?
  # nonzero? also works
  p 'non-empty string'
else
  p 'nil or empty string'
end
snipsnipsnip
la source