Verifica se una variabile è un numero intero


137

Rails 3 o Ruby hanno un modo integrato per verificare se una variabile è un numero intero?

Per esempio,

1.is_an_int #=> true
"dadadad@asdasd.net".is_an_int #=> false?


1
Invece di preoccuparti se una variabile è un numero intero, dovresti verificare se la variabile risponde to_i. Fa parte della "tipizzazione anatra" di Ruby: se può agire come un numero intero, trattalo come tale.
Tin Man

4
@the Tin Man: Non del tutto. "ciao" .to_i restituisce 0 che potrebbe non essere quello che ti aspetti.
EinLama,

1
@AnApprentice Per tua informazione, kind_of?è un alias di is_a?.
Jacob Relkin,

3
@JacobRelkin is_a?è leggermente diverso; chiede se l'oggetto di un'istanza di una classe specifica; kind_of?chiede se si tratta di un'istanza o figlio di una classe specifica. fido.is_a? Dogè vero; fido.kind_of? Animalè vero, per esempio.
Tom Harrison,

Risposte:


274

Puoi usare il is_a?metodo

>> 1.is_a? Integer
=> true
>> "dadadad@asdasd.net".is_a? Integer
=> false
>> nil.is_a? Integer
=> false

2
È molto bello. funziona per convalidare gli indirizzi e-mail?
AnApprentice

65
@AnApprentice Da quando la convalida degli indirizzi e-mail faceva parte della domanda?
Jacob Relkin,

4
questo non funzionerà se il numero arriva in una stringa come "11111111"
Ricbermo,

guarda sotto Integer(obj) rescue false Questo non funzionerà per "1" se vuoi verificare se convertirà
mc.

4
@Ricbermo "1111111" è una stringa. Una stringa che sembra essere convertibile in e intero.
Mq

50

Se vuoi sapere se un oggetto è un Integer o qualcosa che può essere significativamente convertito in un intero (NON includendo cose come "hello", che to_isi convertirà in 0):

result = Integer(obj) rescue false

2
Forse sono solo un noob, ma questo tweak mi avrebbe aiutato. risultato = Integer (obj) rescue false.
John Curry,

@JohnCurry, sentiti libero di modificare la risposta se puoi migliorarla. Ecco come funziona SO.
Alex D,

2
L'ho fatto, è stato respinto. "Questa modifica si discosta dall'intento originale del post" Ma a prescindere, grazie per la tua risposta, mi ha aiutato a risolvere il mio problema!
John Curry,

7
Integer ('08 ') non riuscirà a causa della stringa interpretata come ottale, Integer ('08', 10) funziona bene. Nel caso in cui.
Jong Bor Lee

1
Non sono sicuro che Integer(2.5) => 2sia sempre una conversione significativa.
mkataja,

29

Usa un'espressione regolare su una stringa:

def is_numeric?(obj) 
   obj.to_s.match(/\A[+-]?\d+?(\.\d+)?\Z/) == nil ? false : true
end

Se vuoi verificare se una variabile è di un certo tipo, puoi semplicemente usare kind_of?:

1.kind_of? Integer #true
(1.5).kind_of? Float #true
is_numeric? "545"  #true
is_numeric? "2aa"  #false

Questo è esattamente quello che stavo cercando is_numeric?
workdreamer,

Penso che questo sia vicino, ma non esattamente corretto. Ad esempio, fallirà per ".34". Il problema, a mio avviso, è che \d+?nei ?specifica un match non avido, mentre probabilmente si desidera partite opzionale. Passare \d+?a \d*risolverlo potrebbe risolverlo, ma vorrei essere sicuro di eseguirlo attraverso una serie di test. Anche questo non corrisponderà alla notazione esadecimale o esponenziale, ma sono sicuro che vada bene per alcuni casi d'uso.
Jeff,

1
Perché non utilizzare questa regexp: \A\d+\z?
NARKOZ,

1
Confronta con il Integer(obj) rescue falsecodice da @ alex-d di seguito; regexp è difficile da leggere e non chiaro nelle sue intenzioni. Entrambi funzionano, sono arrivato a questa domanda nel tentativo di risolvere una regexp mal costruita che non sempre funzionava :-)
Tom Harrison,

17

Se non sei sicuro del tipo di variabile (potrebbe trattarsi di una stringa di caratteri numerici), supponi che fosse un numero di carta di credito passato nei parametri, quindi in origine sarebbe una stringa ma vuoi assicurarti che non lo faccia ' Non ci sono caratteri alfabetici, userei questo metodo:

    def is_number?(obj)
        obj.to_s == obj.to_i.to_s
    end

    is_number? "123fh" # false
    is_number? "12345" # true

@Benny sottolinea una svista di questo metodo, tienilo a mente:

is_number? "01" # false. oops!

grazie, mi hai salvato la giornata. Per chiunque abbia bisogno di controllare se galleggia o no, può cambiare direttamente in obj.to_s == obj.to_f.to_sproprio come nel mio caso.
ksugiarto,

Edmund è intelligente! 🙌
siwalikm

Fantastico, preferisco questo rispetto a Integer ('123fh') ed eccezione di salvataggio.
zw963,

6

Puoi usare triple uguale.

if Integer === 21 
    puts "21 is Integer"
end

5

C'è var.is_a? Class(nel tuo caso:) var.is_a? Integer; potrebbe adattarsi al conto. Oppure c'è Integer(var), dove genererà un'eccezione se non può analizzarla.


3

Un modo più "tipografico" è di usare in respond_to?questo modo anche le classi "integer-like" o "string-like"

if(s.respond_to?(:match) && s.match(".com")){
  puts "It's a .com"
else
  puts "It's not"
end

2

Nel caso in cui non sia necessario convertire i valori zero, trovo i metodi to_ie to_fsono estremamente utili poiché convertiranno la stringa in un valore zero (se non convertibile o zero) o nell'effettivo Integero Floatvalore.

"0014.56".to_i # => 14
"0014.56".to_f # => 14.56
"0.0".to_f # => 0.0
"not_an_int".to_f # 0
"not_a_float".to_f # 0.0

"0014.56".to_f ? "I'm a float" : "I'm not a float or the 0.0 float" 
# => I'm a float
"not a float" ? "I'm a float" : "I'm not a float or the 0.0 float" 
# => "I'm not a float or the 0.0 float"

EDIT2: fai attenzione, il 0valore intero non è falso, è verità ( !!0 #=> true) (grazie @prettycoder)

MODIFICARE

Ah, ho appena scoperto i casi oscuri ... sembra accadere solo se il numero è in prima posizione

"12blah".to_i => 12

0 è vero in rubino!
prettycoder

1
@prettycoder grazie per l'heads up, risolverò immediatamente la risposta
Cyril Duchon-Doris

1

Per capitalizzare la risposta di Alex D , usando i perfezionamenti :

module CoreExtensions
  module Integerable
    refine String do
      def integer?
        Integer(self)
      rescue ArgumentError
        false
      else
        true
      end
    end
  end
end

Più tardi, nella tua classe:

require 'core_ext/string/integerable'

class MyClass
  using CoreExtensions::Integerable

  def method
    'my_string'.integer?
  end
end

0

Ho avuto un problema simile prima di provare a determinare se qualcosa è una stringa o qualsiasi tipo di numero. Ho provato a usare un'espressione regolare, ma non è affidabile per il mio caso d'uso. Invece, puoi controllare la classe della variabile per vedere se è un discendente della classe numerica.

if column.class < Numeric
  number_to_currency(column)
else
  column.html_safe
end

In questa situazione, è anche possibile sostituire qualsiasi discendente numerico: BigDecimal, Date :: Infinity, Integer, Fixnum, Float, Bignum, Rational, Complex


-1

Probabilmente stai cercando qualcosa del genere:

Accetta "2.0 o 2.0 come INT ma rifiuta 2.1 e" 2.1 "

num = 2.0

se num.is_a? String num = Float (num) salvataggio false end

new_num = Integer (num) rescue false

mette num

mette new_num

mette num == new_num

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.