2012-04-26 14 views
5

¿Hay un método Ruby que toma una cadena y un valor predeterminado y lo convierte en entero si la cadena representa un entero o devuelve el valor predeterminado de lo contrario?Convertir Ruby String en Integer con el valor predeterminado

actualización Creo que la siguiente respuesta es preferible:

class String 
    def try_to_i(default = nil) 
    /^\d+$/ === self ? to_i : default 
    end 
end 

Aquí es evidencia por las que debe evitar excepciones:

> def time; t = Time.now; yield; Time.now - t end 

> time { 1000000.times { |i| ('_' << i.to_s) =~ /\d+/ } } 
=> 1.3491532 
> time { 1000000.times { |i| Integer.new('_' << i.to_s) rescue nil } } 
=> 27.190596426 
+0

¿Qué quiere decir con "contiene un número entero"? –

+0

'" la optimización prematura es la raíz de todo mal "' - Donald Knuth – Reactormonk

Respuesta

2

que tendrá que codificar que usted mismo, posiblemente usando una expresión regular para verificar la cadena:

def try_to_i(str, default = nil) 
    str =~ /^-?\d+$/ ? str.to_i : default 
end 
+0

¿Qué hay de los números negativos? – Reactormonk

+0

@Tass: Gracias por señalar :) –

8

Hay #to_i y Integer() para convertir. El primero tiene un valor por defecto de 0, el segundo genera un ArgumentError.

class String 
    def to_integer(default) 
    Integer(self) 
    rescue ArgumentError 
    default 
    end 
end 
+0

Creo que el uso de excepciones para casos de uso normal es una sobrecarga de alto rendimiento – Alexey

+0

Tengo que aceptar que esta es la solución más elegante y debe ser aceptada. Solo no sugerí esto porque no sabía acerca de 'Integer()'. @Alexey: La sobrecarga de usar una expresión regular para el trabajo es aún más problemática. –

+0

Niklas, ver la actualización en la pregunta – Alexey

-1

se podría hacer algo como esto:

int_value = (stringVar.match(/^(\d+)$/) && $1.to_i) || default_value 

que verá si la cadena está compuesto enteramente de dígitos, y si es así, convertir a int, o devolver su valor por defecto.

+0

Ruby tiene '?:', Entonces ¿por qué usar el '&& ... || no confiable? ... ¿idiom? –

+0

IMO, parece más bien conceptual agrupar el caso entero en un bloque entre paréntesis, en lugar de usar el operador ternario. Además, ¿cómo es &&/|| ¿no fidedigno? Claro, existe la cuestión de la precedencia si cambia entre sus operadores equivalentes de la palabra escrita (o/y), pero el uso constante lo elimina. Dicho todo esto, depende de ti; si el ternario se adapta a tu estilo, hazlo. –

+0

Quise decir el hecho de que siempre hay que pensar dos veces si la parte entre '&&' y '||' puede convertirse en 'false' o' nil', en cuyo caso no es equivalente al operador condicional o 'si ... entonces .. else'. En este caso, está bien porque 'to_i' siempre devuelve un valor entero. Por cierto, los paréntesis no son necesarios en tu ejemplo. –

Cuestiones relacionadas