2009-06-16 18 views
155

Esto es lo que tengo ahora, que parece demasiado prolijo para el trabajo que está haciendo.¿Cuál es la forma canónica de recortar una cadena en Ruby sin crear una nueva cadena?

@title  = tokens[Title].strip! || tokens[Title] if !tokens[Title].nil? 

Asumir tokens es una matriz obtenida al dividir una línea CSV. ahora las funciones como strip! ¡chomp! et. todos nula rentabilidad si la cadena no se modificó

"abc".strip! # => nil 
" abc ".strip! # => "abc" 

Cuál es la forma de Ruby decir recortarlo si contiene líder adicional o espacios finales sin crear copias?

se vuelve más delicada si quiero hacer tokens[Title].chomp!.strip!

+3

Si va a leer cosas de tokens repetidamente, podría tener más sentido preprocesarlas. Es decir, "tokens.each {| t | t.strip!}". entonces puedes hacer "@title = tokens [Título] || ''" –

Respuesta

227

supongo que lo que quiere decir:

@title = tokens[Title] 
@title.strip! 

El método #strip! volverá nil si no se tira nada, y la propia variable si fue despojado

Según los estándares de Ruby, un método con un sufijo con un signo de exclamación cambia la variable en su lugar.

Espero que esto ayude.

Actualización: Esta es la salida de irb para demostrar:

>> @title = "abc" 
=> "abc" 
>> @title.strip! 
=> nil 
>> @title 
=> "abc" 
>> @title = " abc " 
=> " abc " 
>> @title.strip! 
=> "abc" 
>> @title 
=> "abc" 
+0

Hmm ... aún así creo @title = tokens [Título] .strip! se ve más limpio - es una pena que devuelva nil en lugar de la cadena sin modificar. A menos que alguien publique una mejor respuesta ... obtendrá el bit aceptado. – Gishu

+5

Bueno, @title = tokens [Title] .strip hará el truco pero tendrías una copia, lo cual está bien si mantienes intacta la variable tokens [Title]. – Igor

+0

Si desea que un método devuelva la cadena sin modificar, puede crear fácilmente su propia tira: def strip_returning_self(). || autodirigido – Chuck

2

Creo que su ejemplo es un enfoque razonable, aunque se podría simplificar ligeramente como:

@title = tokens[Title].strip! || tokens[Title] if tokens[Title] 

alternativo puede ponerlo en dos líneas:

@title = tokens[Title] || '' 
@title.strip! 
8

No es necesario que se desforre y muerda, ya que strip también eliminará los retornos del carro posterior, a menos que haya cambiado el separador de registros predeterminado y eso es lo que está masticando.

respuesta de Olly ya tiene la forma canónica de hacer esto en Ruby, aunque si usted se encuentra haciendo esto mucho siempre se puede definir un método para ello:

def strip_or_self!(str) 
    str.strip! || str 
end 

Dar:

@title = strip_or_self!(tokens[Title]) if tokens[Title] 

También tenga en cuenta que la instrucción if evitará que se asigne @title si el token es nulo, lo que hará que conserve su valor anterior.Si usted quiere o no le importa @title siempre que se asigne puede mover el cheque en el método y reducir aún más la duplicación:

def strip_or_self!(str) 
    str.strip! || str if str 
end 

Como alternativa, si se siente aventurero puede definir un método en sí Cadena :

class String 
    def strip_or_self! 
    strip! || self 
    end 
end 

Dar uno de:

@title = tokens[Title].strip_or_self! if tokens[Title] 

@title = tokens[Title] && tokens[Title].strip_or_self! 
+0

Aunque técnicamente no es la respuesta. Gracias ... no sabía eso ... – Gishu

44

Por cierto, ahora ya es compatible con el rubí simplemente tira sin "!".

Compare:

p "abc".strip! == " abc ".strip! # false, because "abc".strip! will return nil 
p "abc".strip == " abc ".strip # true 

También es imposible strip sin duplicados. Ver las fuentes en string.c:

static VALUE 
rb_str_strip(VALUE str) 
{ 
    str = rb_str_dup(str); 
    rb_str_strip_bang(str); 
    return str; 
} 

1.9.3p0 rubí (2011-10-30) [i386-mingw32]

Actualización 1: Tal como lo veo ahora - que fue creado en 1999 año (véase rev #372 en SVN):

Update2: strip! no creará duplicados - tanto en 1.9.x, 2.x versiones y el tronco.

+0

"es imposible pelar sin duplicados" - por supuesto que es posible, ¡para eso es 'strip!'. –

+0

@KarolyHorvath ¿no ves el código fuente, escrito en C? Pls leyó cuidadosamente, lo que escribí aquí con respecto a los duplicados. – gaRex

+0

Por supuesto que lo veo. Pero ese es el código fuente de 'strip'. ¿Estoy malinterpretando algo? ¿De qué otra manera podría interpretar "imposible de pelar sin duplicado"? –

2

Mi manera:

> (@title = " abc ").strip! 
=> "abc" 
> @title 
=> "abc" 
0
@title = tokens[Title].strip! || tokens[Title] 

Es muy posible que no soy la comprensión del tema, pero ¿no sería esto hacer lo que tiene?

" success ".strip! || "rescue" #=> "success" 
"failure".strip! || "rescue" #=> "rescue" 
1

Si usted tiene cualquiera de rubí 1.9 o ActiveSupport, puede hacerlo simplemente

@title = tokens[Title].try :tap, &:strip! 

Esto es realmente genial, ya que aprovecha la :try y el método :tap, que son las construcciones funcionales más poderosos de ruby, en mi opinión.

Una forma aún más lindo, pasando funciones como símbolos completo:

@title = tokens[Title].send :try, :tap, &:strip! 
5

Si está usando Ruby on Rails no es una desplazamiento de la mezcla

> @title = " abc " 
=> " abc " 

> @title.squish 
=> "abc" 
> @title 
=> " abc " 

> @title.squish! 
=> "abc" 
> @title 
=> "abc" 

Si está utilizando simplemente Rubí que quieren para usar tira

Aquí está el gotcha .. en su caso, usted desea utilizar s viaje sin la explosión!

mientras tira! ciertamente devuelve nulo si no hubo acción, todavía actualiza la variable, ¡así que quítate! no se puede usar en línea ¡Si quiere usar strip inline puede usar la versión sin el bang!

strip! usando enfoque multi línea

> tokens["Title"] = " abc " 
=> " abc " 
> tokens["Title"].strip! 
=> "abc" 
> @title = tokens["Title"] 
=> "abc" 

tira enfoque sola línea ... SU RESPUESTA

> tokens["Title"] = " abc " 
=> " abc " 
> @title = tokens["Title"].strip if tokens["Title"].present? 
=> "abc" 
2

Si desea utilizar otro método después de que necesita algo como esto:

(str.strip || str).split(',') 

De esta manera puede desnudarse y aún hacer algo después :)

Cuestiones relacionadas