J'ai besoin d'une fonction is_an_integer
, où
"12".is_an_integer?
renvoie vrai."blah".is_an_integer?
renvoie false.
Comment puis-je faire cela dans Ruby? J'écrirais une regex mais je suppose qu'il y a une aide pour cela dont je ne suis pas au courant.
Réponses:
Vous pouvez utiliser des expressions régulières. Voici la fonction avec les suggestions de @ janm.
Une version modifiée selon le commentaire de @wich:
Au cas où vous auriez seulement besoin de vérifier les nombres positifs
la source
/regexp/ === self
place de la!!(self =~ /regexp/)
construction. Vous pouvez utiliser la classe de caractères '\ d' au lieu de[0-9]
Eh bien, voici le moyen le plus simple:
Je ne suis pas d'accord avec les solutions qui provoquent une exception pour convertir la chaîne - les exceptions ne sont pas un flux de contrôle, et vous pourriez aussi bien le faire de la bonne manière. Cela dit, ma solution ci-dessus ne traite pas des entiers non en base 10. Alors, voici comment faire sans recourir à des exceptions:
la source
self.to_i.to_s == self
parInteger self rescue false
?Vous pouvez utiliser
Integer(str)
et voir si cela augmente:Il convient de souligner que même si cela renvoie vrai pour
"01"
, il ne le fait pas pour"09"
, simplement parce que09
ce ne serait pas un littéral entier valide. Si ce n'est pas le comportement souhaité, vous pouvez ajouter10
comme deuxième argument àInteger
, de sorte que le nombre est toujours interprété comme base 10.la source
#to_i
sont tout simplement trop brisées à cause de leur permissivité.Integer()
est canonique carInteger ()
vous savez avec certitude que tout ce que Ruby considère comme un entier littéral sera accepté, et tout le reste sera rejeté. Dupliquer ce que le langage vous donne déjà est sans doute une odeur de code pire que d'utiliser des exceptions pour le contrôle.Vous pouvez faire une seule ligne:
ou même
En fonction de ce que vous essayez de faire, vous pouvez également utiliser directement un bloc de début de fin avec une clause de sauvetage:
la source
la source
true
etfalse
mais desMatchData
instances etnil
!!
ou utilisez-lepresent?
si vous avez besoin d'un booléen!!( "12".match /^(\d)+$/ )
ou"12".match(/^(\d)+$/).present?
(ce dernier nécessitant Rails / actifsupport)Ruby 2.6.0 permet la conversion en un entier sans lever d'exception , et retournera
nil
si la conversion échoue. Et commenil
se comporte principalement commefalse
dans Ruby, vous pouvez facilement vérifier un entier comme ceci:la source
is_
. Je trouve cela idiot sur les méthodes de point d'interrogation, j'aime"04".integer?
beaucoup mieux que"foo".is_integer?
."01"
et ainsi de suite.la source
integer?("a string")
ftl.String#integer?
est le genre de patch commun que chaque codeur Ruby et son cousin aiment ajouter au langage, conduisant à des bases de code avec trois implémentations différentes subtilement incompatibles et une rupture inattendue. J'ai appris cela à la dure sur de grands projets Ruby.La meilleure et la plus simple consiste à utiliser
Float
Integer
c'est aussi bien mais ça reviendra0
pourInteger nil
la source
Je préfère:
config / initialiseurs / string.rb
puis:
ou vérifiez le numéro de téléphone:
la source
Un moyen beaucoup plus simple pourrait être
la source
la source
Personnellement, j'aime l'approche d'exception même si je la rendrais un peu plus laconique:
Cependant, comme d'autres l'ont déjà indiqué, cela ne fonctionne pas avec les chaînes Octal.
la source
Ruby 2.4 a
Regexp#match?
: (avec a?
)Pour les anciennes versions de Ruby, il y a
Regexp#===
. Et bien que l'utilisation directe de l'opérateur d'égalité de cas devrait généralement être évitée, cela semble très clair ici:la source
Cela peut ne pas convenir à tous les cas en utilisant simplement:
pourrait aussi faire pour certains.
S'il s'agit d'un nombre et non de 0, il renverra un nombre. S'il renvoie 0, c'est soit une chaîne, soit 0.
la source
"12blah".to_i => 12
. Cela pourrait causer des problèmes dans des scénarios étranges.Voici ma solution:
Et voici comment cela fonctionne:
/^(\d)+$/
est une expression regex pour trouver des chiffres dans n'importe quelle chaîne. Vous pouvez tester vos expressions et résultats regex sur http://rubular.com/ .IntegerRegex
pour éviter une allocation de mémoire inutile à chaque fois que nous l'utilisons dans la méthode.integer?
est une méthode interrogative qui devrait renvoyertrue
oufalse
.match
est une méthode sur chaîne qui correspond aux occurrences selon l'expression regex donnée en argument et renvoie les valeurs correspondantes ounil
.!!
convertit le résultat dematch
method en booléen équivalent.String
classe existante est une correction de singe, qui ne change rien aux fonctionnalités String existantes, mais ajoute simplement une autre méthode nomméeinteger?
sur n'importe quel objet String.la source
En développant la réponse de @ rado ci-dessus, on pourrait également utiliser une instruction ternaire pour forcer le retour de booléens vrais ou faux sans utiliser de double frange. Certes, la version à double négation logique est plus laconique, mais probablement plus difficile à lire pour les nouveaux venus (comme moi).
la source
Pour les cas plus généralisés (y compris les nombres avec point décimal), vous pouvez essayer la méthode suivante:
Vous pouvez tester cette méthode dans une session irb:
Pour une explication détaillée de l'expression régulière impliquée ici, consultez cet article de blog :)
la source
obj.is_a? String
car String # to_s se retournera, ce qui, je suppose, ne nécessite pas trop de traitement par rapport à l'.is_a?
appel. De cette façon, vous ne ferez qu'un seul appel sur cette ligne au lieu d'un ou deux. Vous pouvez également inclure directement!!
dans lanumber?
méthode, car par convention, un nom de méthode qui se termine par?
est censé renvoyer une valeur booléenne. Cordialement!J'aime ce qui suit, simple:
Attention cependant:
la source
Une doublure en
string.rb
la source
Je ne sais pas si c'était le cas lorsque cette question est posée, mais pour quiconque tombe sur ce post, le moyen le plus simple est:
.is_a?
fonctionnera avec n'importe quel objet.la source
"12".is_an_integer? == true
"not12".is_an_integer? == false
12.is_an_integer? == true