2012-04-10 12 views
28

Dado un objeto de cadena como esta:Diferencia entre Entero (valor) y value.to_i

twohundred = "200" 

¿Cuál es la diferencia entre hacer:

Integer(twohundred) #=> 200 

y:

twohundred.to_i  #=> 200 

Hay alguna diferencia? ¿Se recomienda usar uno entre el otro?

Respuesta

35

Integer(num) lanzará una excepción ArgumentError si num no es un número entero válido (puede especificar la base).

num.to_i convertirá todo lo que pueda.

Por ejemplo:

"2hi".to_i 
#=> 2 

Integer("2hi") 
#=> throws ArgumentError 

"hi".to_i 
#=> 0 

Integer("hi") 
#=> throws ArgumentError 

"2.0".to_i 
#=> 2 

Integer("2.0") 
#=> throws ArgumentError 
+0

Awesome answer. Gracias. – Nobita

+0

Tenga en cuenta que puede especificar la base para ambos, ['Kernel # Integer'] (http://ruby-doc.org/core-2.3.1/Kernel.html#method-i-Integer) y [' String # to_i'] (http://ruby-doc.org/core-2.3.1/String.html#method-i-to_i). – Stefan

+0

Otro caso notable es '' 'nil.to_i # => 0''', mientras que' '' Integer (nil) # => arroja TypeError: no puede convertir nil en Entero''' – Levsero

8

Desde el Rubí documentation para Integer():

Integer(arg,base=0) → integer ... If arg is a String, when base is omitted or equals to zero, radix indicators (0, 0b, and 0x) are honored. In any case, strings should be strictly conformed to numeric representation. This behavior is different from that of String#to_i.

En otras palabras, Integer("0x100") => 256 y "0x100".to_i => 0.

+0

p. '" 0x10 ".to_i' da' 0', mientras 'entero (" 0x10 ")' da '16' – Phrogz

+0

' "0x10" .to_i (16) 'pero también da' 16'. – Stefan

0

Examinemos las diferencias entre utilizar el método de instancia String#to_i y el método de módulo Kernel::Integer. En primer lugar, sin embargo, vamos a incrustar la tarde en otro método int1:

def int1(str) 
    Integer(str) rescue nil 
end 

esta manera, si str no puede interpretarse como un entero, Integer lanzará una excepción ArgumentError, haciendo que el rescate en línea para volver nil. Si Integer no genera una excepción int devolverá el entero equivalente de la cadena.

Para completar las comparaciones, agreguemos una expresión regular que confirme que el contenido de la cadena representa un número entero antes de usar to_i para realizar la conversión.

R =/
    (?<=\A|\s) # match beginning of string or whitespace character (positive lookbehind) 
    -?   # optionally match a minus sign 
    \d+  # match one or more digits 
    (?=\s|\z) # match whitespace character or end of string (positive lookahead) 
    /x   # free spacing regex definition mode 

def int2(str) 
    str =~ R ? str.to_i : nil 
end 

Como con int1, si str no puede interpretarse como un entero, int2 volverá nil; else, int devuelve el entero equivalente de la cadena.

Probemos algunas comparaciones.

str = '3' 
str.to_i  #=> 3 
int1(str)  #=> 3 
int2(str)  #=> 3 

str = '-3' 
str.to_i  #=> -3 
int1(str)  #=> -3 
int2(str)  #=> -3 

str = '3.0' 
str.to_i  #=> 3 
int1(str)  #=> nil 
int2(str)  #=> nil 

str = '3.2' 
str.to_i  #=> 3 
int1(str)  #=> nil 
int2(str)  #=> nil 

1e3   #=> 1000.0 
str = '1e3' 
str.to_i  #=> 1 
int1(str)  #=> nil 
int2(str)  #=> nil 

str = '-1e3' 
str.to_i  #=> -1 
int1(str)  #=> nil 
int2(str)  #=> nil 

str = '- 1e3' 
str.to_i  #=> 0 
int1(str)  #=> nil 
int2(str)  #=> nil 

str = '3a' 
str.to_i  #=> 3 
int1(str)  #=> nil 
int2(str)  #=> nil 

str = '1-3a' 
str.to_i  #=> 1 
int1(str)  #=> nil 
int2(str)  #=> nil 

str = 'b3' 
str.to_i  #=> 0 
int1(str)  #=> nil 
int2(str)  #=> nil 

String#to_i lee dígitos (posiblemente precedido por un signo menos) hasta que lea un carácter de espacio en blanco o llega al final de la cadena. A continuación, simplemente convierte esos dígitos y posible signo menos a Fixnum, que devuelve. to_i ciertamente tiene sus usos, pero estos ejemplos muestran que debe usar int1 o int2 si desea devolver nil si la cadena no contiene la representación de un número entero.

Cuestiones relacionadas