Edité mi respuesta, por lo que podría ser posible cambiar la respuesta seleccionada. Vea si puede otorgarlo a la respuesta de Jason Stirk, ya que la suya es la más rápida y es muy legible.
The Tin Man
3
Use str [1 ..- 1], es el más rápido según las respuestas a continuación.
Achyut Rastogi
1
A partir de Ruby 2.5 puede usar delete_prefixy delete_prefix!- más detalles a continuación . No he tenido tiempo de comparar, ¡pero lo haré pronto!
SRack
Actualización: he comparado los nuevos métodos ( delete_prefix\ delete_prefix!) y son bastante rápidos. No superan a los favoritos anteriores por la velocidad, pero la legibilidad significa que son excelentes opciones nuevas para tener.
1.9.3
user system total real
[0]0.8400000.0000000.840000(0.847496)
sub 1.9600000.0100001.970000(1.962767)
gsub 4.3500000.0200004.370000(4.372801)[1..-1]0.7100000.0000000.710000(0.713366)
slice 1.0200000.0000001.020000(1.020336)
length 1.1600000.0000001.160000(1.157882)
Actualización para incorporar una respuesta sugerida más:
2.1.2
user system total real
[0]0.3000000.0000000.300000(0.295054)
sub 0.6300000.0000000.630000(0.631870)
gsub 2.0900000.0000002.090000(2.094368)[1..-1]0.2300000.0100000.240000(0.232846)
slice 0.3200000.0000000.320000(0.320714)
length 0.3400000.0000000.340000(0.341918)
eat!0.4600000.0000000.460000(0.452724)
reverse 0.4000000.0000000.400000(0.399465)
Y otro que usa /^./para encontrar el primer personaje:
Aquí hay otra actualización sobre hardware más rápido y una versión más nueva de Ruby:
2.3.1
user system total real
[0]0.2000000.0000000.200000(0.204307)[/^./]0.3900000.0000000.390000(0.387527)[/^\[/]0.3600000.0000000.360000(0.360400)
sub+0.4900000.0000000.490000(0.492083)
sub 0.4800000.0000000.480000(0.487862)
gsub 1.9900000.0000001.990000(1.988716)[1..-1]0.1800000.0000000.180000(0.181673)
slice 0.2600000.0000000.260000(0.266371)
length 0.2700000.0000000.270000(0.267651)
eat!0.4000000.0100000.410000(0.398093)
reverse 0.3400000.0000000.340000(0.344077)
¿Por qué es tan lento gsub?
Después de hacer una búsqueda / reemplazo, gsubtiene que verificar posibles coincidencias adicionales antes de que pueda saber si ha terminado. subsolo hace uno y termina. Considere gsubque es un mínimo de dos subllamadas.
Además, es importante recordar eso gsub, y subtambién puede verse obstaculizado por expresiones regulares mal escritas que coinciden mucho más lentamente que una búsqueda de subcadenas. Si es posible, ancle la expresión regular para obtener la mayor velocidad posible. Hay respuestas aquí en Stack Overflow que lo demuestran, así que busque si desea obtener más información.
Es importante tener en cuenta que esto solo funcionará en Ruby 1.9. En Ruby 1.8, esto eliminará el primer byte de la cadena, no el primer carácter, que no es lo que quiere el OP.
Jörg W Mittag
+1: Siempre olvido que a una posición de cadena puede asignar no solo un solo carácter, sino que también puede insertar una subcadena. ¡Gracias!
quetzalcoatl
"[12,23,987,43".delete "["
rupweb
44
Eso lo elimina de todas las posiciones, que no es lo que el OP quería: "... para el primer personaje?".
The Tin Man
2
" what about "[12,23,987,43".shift ?"? ¿Qué pasa con "[12,23,987,43".shift NoMethodError: undefined method shift 'para "[12,23,987,43": String`?
The Tin Man
293
Similar a la respuesta de Pablo anterior, pero un limpiador de sombra:
+1 Eche un vistazo a los resultados de referencia que agregué a mi respuesta. Tienes el tiempo de ejecución más rápido, además creo que es muy limpio.
The Tin Man
¿Qué pasa con el rendimiento en str[1,]comparación con lo anterior?
Bohr
1
@Bohr: str[1,]devuelve el segundo personaje ya que el rango es 1:nil. Tendría que proporcionar la longitud calculada real, o algo garantizado para ser mayor que la longitud, como, str[1,999999](use int_max, por supuesto) para obtener toda la cola. [1..-1]es más limpio y probablemente más rápido, ya que no necesita operar manualmente en longitud (vea [1..length] en el punto de referencia)
quetzalcoatl
44
Muy buena solución. Por cierto, si uno quiere eliminar el primer y último carácter:str[1..-2]
pisaruk
50
Podemos usar slice para hacer esto:
val ="abc"=>"abc"
val.slice!(0)=>"a"
val
=>"bc"
Usando slice!podemos eliminar cualquier carácter especificando su índice.
Este elegante slice!(0)realmente debería ser la respuesta seleccionada, ya que usar asdf[0] = '' para eliminar el primer personaje es ridículo (al igual que usar gsub con regex y disparar una mosca con un obús).
f055
1
Si bien puede parecer poco intuitivo en la superficie, []=no requiere tanto código C subyacente, donde se slice!requiere trabajo adicional. Eso suma. El argumento podría ser "¿Cuál es más legible?" Me parece []=legible, pero vengo de un fondo C -> Perl que probablemente colorea mi pensamiento. Los desarrolladores de Java probablemente pensarían que es menos legible. Cualquiera de las dos es una forma aceptable de llevar a cabo la tarea siempre que se entienda y se pueda mantener fácilmente y no cargue la CPU de manera indebida.
The Tin Man
Okay. ¿Sabes cómo podemos medir si una función requiere mucha carga de CPU en ROR? ¿o deberíamos usar la diferencia de tiempo de ejecución en mili o nanosegundos?
balanv
18
Ruby 2.5+
A partir de Ruby 2.5 puede usar delete_prefixo delete_prefix!lograr esto de manera legible.
Usando la configuración de referencia de Tin Man, también se ve bastante rápido (en las últimas dos entradas delete_py delete_p!). No bastante pip los favoritos anteriores para la velocidad, aunque es muy legible.
2.5.0
user system total real
[0]0.1747660.0004890.175255(0.180207)[/^./]0.3180380.0005100.318548(0.323679)[/^\[/]0.3726450.0011340.373779(0.379029)
sub+0.4602950.0015100.461805(0.467279)
sub 0.4983510.0015340.499885(0.505729)
gsub 1.6698370.0051411.674978(1.682853)[1..-1]0.1998400.0009760.200816(0.205889)
slice 0.2796610.0008590.280520(0.285661)
length 0.2683620.0003100.268672(0.273829)
eat!0.3417150.0005240.342239(0.347097)
reverse 0.3353010.0005880.335889(0.340965)
delete_p 0.2222970.0008320.223129(0.228455)
delete_p!0.2257980.0007470.226545(0.231745)
Yo usaría en "[12,23,987,43".sub(/^\[+/, "")lugar de gsub(/^\[/, ""). El primero permite que el motor regex encuentre todas las coincidencias, luego se reemplazan en una acción y da como resultado una mejora de la velocidad de 2x con Ruby 1.9.3.
The Tin Man
1
Ya que estamos tratando con cadenas, ¿debería ser esto gsub(/\A\[/, "") ?
1.9.2-p290 > a ="One Two Three"=>"One Two Three"1.9.2-p290 > a = a[1..-1]=>"ne Two Three"1.9.2-p290 > a = a[1..-1]=>"e Two Three"1.9.2-p290 > a = a[1..-1]=>" Two Three"1.9.2-p290 > a = a[1..-1]=>"Two Three"1.9.2-p290 > a = a[1..-1]=>"wo Three"
De esta forma, puede eliminar uno por uno el primer carácter de la cadena.
Si desea preservar la semántica de "corte", podría simplemente"[12,23,987,43".reverse.chop.reverse
Chris Heald el
esa es una gran sobrecarga de rendimiento solo para quitar un personaje
Pablo Fernandez
77
¿por qué no usar [1 ..- 1] en lugar de [1..self.length]?
horseyguy
El ejemplo de parches de mono está bastante mal para esta pregunta, es simplemente irrelevante y feo IMO.
dredozubov
3
¡Gracias a @ the-tin-man por armar los puntos de referencia!
Por desgracia, no me gusta ninguna de esas soluciones. O requieren un paso adicional para obtener el resultado ( [0] = '', .strip!) o no son muy semánticos / claros sobre lo que está sucediendo ( [1..-1]: "¿Um, un rango de 1 a 1 negativo? ¿Año?"), O son lentos o largos para escribir ( .gsub, .length).
Lo que estamos intentando es un 'cambio' (en lenguaje Array), pero devolviendo los caracteres restantes, en lugar de lo que se cambió. ¡Usemos nuestro Ruby para hacer esto posible con cadenas! Podemos usar la operación de soporte rápido, pero asígnele un buen nombre y tome una discusión para especificar cuánto queremos cortar:
Pero hay más que podemos hacer con esa operación de soporte rápida pero difícil de manejar. Mientras estamos en ello, para completar, escribamos un #shifty #firstpara String (¿por qué Array debería divertirse?), Tomando un argumento para especificar cuántos caracteres queremos eliminar desde el principio:
classStringdef first(how_many =1)self[0...how_many]enddef shift(how_many =1)
shifted = first(how_many)self.replace self[how_many..-1]
shifted
end
alias_method :shift!,:shift
end
Bien, ahora tenemos una buena forma clara de extraer caracteres del frente de una cadena, con un método que sea consistente con Array#firsty Array#shift(¿cuál debería ser realmente un método de explosión?). Y también podemos obtener fácilmente la cadena modificada con #eat!. ¿Deberíamos compartir nuestro nuevo eat!poder con Array? ¡Por qué no!
Recuerdo una discusión hace años en los foros de Perl acerca de tal función con el nombre de en chip()lugar de chop()(y chimp()como el análogo de chomp()).
Es importante tener en cuenta que esto solo funcionará en Ruby 1.9. En Ruby 1.8, esto eliminará el primer byte de la cadena, no el primer carácter, que no es lo que quiere el OP.
Jörg W Mittag
0
classStringdef bye_felicia()
felicia =self.strip[0]#first char, not first space.self.sub(felicia,'')endend
delete_prefix
ydelete_prefix!
- más detalles a continuación . No he tenido tiempo de comparar, ¡pero lo haré pronto!delete_prefix
\delete_prefix!
) y son bastante rápidos. No superan a los favoritos anteriores por la velocidad, pero la legibilidad significa que son excelentes opciones nuevas para tener.Respuestas:
Estoy a favor de usar algo como:
Siempre estoy buscando la forma más rápida y fácil de hacer las cosas:
Ejecutando en mi Mac Pro:
Actualización para incorporar una respuesta sugerida más:
Lo que resulta en:
Y otro que usa
/^./
para encontrar el primer personaje:Lo que resulta en:
Aquí hay otra actualización sobre hardware más rápido y una versión más nueva de Ruby:
Después de hacer una búsqueda / reemplazo,
gsub
tiene que verificar posibles coincidencias adicionales antes de que pueda saber si ha terminado.sub
solo hace uno y termina. Consideregsub
que es un mínimo de dossub
llamadas.Además, es importante recordar eso
gsub
, ysub
también puede verse obstaculizado por expresiones regulares mal escritas que coinciden mucho más lentamente que una búsqueda de subcadenas. Si es posible, ancle la expresión regular para obtener la mayor velocidad posible. Hay respuestas aquí en Stack Overflow que lo demuestran, así que busque si desea obtener más información.fuente
"[12,23,987,43".delete "["
what about "[12,23,987,43".shift ?
"? ¿Qué pasa con"[12,23,987,43".shift NoMethodError: undefined method
shift 'para "[12,23,987,43": String`?Similar a la respuesta de Pablo anterior, pero un limpiador de sombra:
Devolverá la matriz de 1 al último carácter.
fuente
str[1,]
comparación con lo anterior?str[1,]
devuelve el segundo personaje ya que el rango es1:nil
. Tendría que proporcionar la longitud calculada real, o algo garantizado para ser mayor que la longitud, como,str[1,999999]
(use int_max, por supuesto) para obtener toda la cola.[1..-1]
es más limpio y probablemente más rápido, ya que no necesita operar manualmente en longitud (vea [1..length] en el punto de referencia)str[1..-2]
Podemos usar slice para hacer esto:
Usando
slice!
podemos eliminar cualquier carácter especificando su índice.fuente
slice!(0)
realmente debería ser la respuesta seleccionada, ya que usarasdf[0] = ''
para eliminar el primer personaje es ridículo (al igual que usar gsub con regex y disparar una mosca con un obús).[]=
no requiere tanto código C subyacente, donde seslice!
requiere trabajo adicional. Eso suma. El argumento podría ser "¿Cuál es más legible?" Me parece[]=
legible, pero vengo de un fondo C -> Perl que probablemente colorea mi pensamiento. Los desarrolladores de Java probablemente pensarían que es menos legible. Cualquiera de las dos es una forma aceptable de llevar a cabo la tarea siempre que se entienda y se pueda mantener fácilmente y no cargue la CPU de manera indebida.Ruby 2.5+
A partir de Ruby 2.5 puede usar
delete_prefix
odelete_prefix!
lograr esto de manera legible.En este caso
"[12,23,987,43".delete_prefix("[")
.Más información aquí:
Documentos oficiales
https://blog.jetbrains.com/ruby/2017/10/10-new-features-in-ruby-2-5/
https://bugs.ruby-lang.org/issues/12694
Nota: también puede usar esto para eliminar elementos del final de una cadena con
delete_suffix
ydelete_suffix!
Editar:
Usando la configuración de referencia de Tin Man, también se ve bastante rápido (en las últimas dos entradas
delete_p
ydelete_p!
). No bastante pip los favoritos anteriores para la velocidad, aunque es muy legible.fuente
Prefiero esto:
fuente
Si siempre quieres quitar los corchetes:
Si solo desea eliminar el primer carácter y sabe que no estará en un conjunto de caracteres multibyte:
o
fuente
"[12,23,987,43".sub(/^\[+/, "")
lugar degsub(/^\[/, "")
. El primero permite que el motor regex encuentre todas las coincidencias, luego se reemplazan en una acción y da como resultado una mejora de la velocidad de 2x con Ruby 1.9.3.gsub(/\A\[/, "")
?Alternativa ineficiente:
fuente
Por ejemplo: a = "One Two Three"
De esta forma, puede eliminar uno por uno el primer carácter de la cadena.
fuente
Manera fácil:
Manera impresionante:
(Nota: prefiera la manera fácil :))
fuente
"[12,23,987,43".reverse.chop.reverse
¡Gracias a @ the-tin-man por armar los puntos de referencia!
Por desgracia, no me gusta ninguna de esas soluciones. O requieren un paso adicional para obtener el resultado (
[0] = ''
,.strip!
) o no son muy semánticos / claros sobre lo que está sucediendo ([1..-1]
: "¿Um, un rango de 1 a 1 negativo? ¿Año?"), O son lentos o largos para escribir (.gsub
,.length
).Lo que estamos intentando es un 'cambio' (en lenguaje Array), pero devolviendo los caracteres restantes, en lugar de lo que se cambió. ¡Usemos nuestro Ruby para hacer esto posible con cadenas! Podemos usar la operación de soporte rápido, pero asígnele un buen nombre y tome una discusión para especificar cuánto queremos cortar:
Pero hay más que podemos hacer con esa operación de soporte rápida pero difícil de manejar. Mientras estamos en ello, para completar, escribamos un
#shift
y#first
para String (¿por qué Array debería divertirse?), Tomando un argumento para especificar cuántos caracteres queremos eliminar desde el principio:Bien, ahora tenemos una buena forma clara de extraer caracteres del frente de una cadena, con un método que sea consistente con
Array#first
yArray#shift
(¿cuál debería ser realmente un método de explosión?). Y también podemos obtener fácilmente la cadena modificada con#eat!
. ¿Deberíamos compartir nuestro nuevoeat!
poder con Array? ¡Por qué no!Ahora podemos:
¡Eso es mejor!
fuente
chip()
lugar dechop()
(ychimp()
como el análogo dechomp()
).fuente
fuente
Usando regex:
fuente
Encuentro una buena solución
str.delete(str[0])
para su legibilidad, aunque no puedo dar fe de su rendimiento.fuente
List elimina uno o más elementos desde el inicio de la matriz, no muta la matriz y devuelve la matriz en sí misma en lugar del elemento descartado.
fuente