Eu editei minha resposta, para que seja possível alterar a resposta selecionada. Veja se você pode atribuir a resposta de Jason Stirk, já que a dele é a mais rápida e muito legível.
the Tin Man
3
Use str [1 ..- 1], o mais rápido, de acordo com as respostas abaixo.
Achyut Rastogi
1
A partir do Ruby 2.5, você pode usar delete_prefixe delete_prefix!- mais detalhes abaixo . Ainda não tive tempo de avaliar, mas o farei em breve!
SRack
Atualização: comparei os novos métodos ( delete_prefix\ delete_prefix!) e eles são bem rápidos. Eles não são exatamente os favoritos anteriores em termos de velocidade, mas a legibilidade significa que são ótimas novas opções!
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)
Atualizando para incorporar mais uma resposta sugerida:
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)
E outro usando /^./para encontrar o primeiro caractere:
Aqui está outra atualização de hardware mais rápido e uma versão mais recente do 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 que o gsub é tão lento?
Depois de fazer uma pesquisa / substituição, gsubé necessário verificar possíveis correspondências adicionais antes de saber se está finalizado. subsó faz um e termina. Considere gsubum mínimo de duas subchamadas.
Além disso, é importante lembrar que gsub, e subtambém pode ser prejudicado por regex mal escrito que corresponder muito mais lentamente do que uma busca sub-string. Se possível, ancore o regex para obter o máximo de velocidade dele. Há respostas aqui no Stack Overflow demonstrando que, então, procure se deseja mais informações.
É importante notar que isso só funcionará no Ruby 1.9. No Ruby 1.8, isso removerá o primeiro byte da string, não o primeiro caractere, que não é o que o OP deseja.
Jörg W Mittag
+1: sempre esqueço que, para uma posição de string, você pode atribuir não apenas um caractere, mas também pode inserir uma substring. Obrigado!
Quetzalcoatl
"[12,23,987,43".delete "["
rupweb
4
Isso o exclui de todas as posições, o que não é o que o OP queria: "... para o primeiro personagem?".
the Tin Man
2
" what about "[12,23,987,43".shift ?"? E quanto a "[12,23,987,43".shift NoMethodError: undefined method shift 'for "[12,23,987,43": String`?
o homem de lata
293
Semelhante à resposta de Pablo acima, mas um limpador de sombra:
+1 Veja os resultados de referência que adicionei à minha resposta. Você tem o tempo de execução mais rápido, e acho que é muito limpo.
the Tin Man
E o desempenho do str[1,]comparado com o acima?
Bohr
1
@ Bohr: str[1,]retorna o segundo caractere, pois o intervalo é 1:nil. Você precisaria fornecer o comprimento calculado real ou algo garantido para ser maior que o comprimento, como str[1,999999](use int_max, é claro) para obter a cauda inteira. [1..-1]é mais limpo e provavelmente mais rápido, já que você não precisa para operar no comprimento manualmente (veja [1..length] no benchmark)
quetzalcoatl
4
Solução muito boa. A propósito, se alguém quiser remover o primeiro e o último caracteres:str[1..-2]
pisaruk 19/12/2014
50
Podemos usar a fatia para fazer isso:
val ="abc"=>"abc"
val.slice!(0)=>"a"
val
=>"bc"
Usando slice!podemos excluir qualquer caractere especificando seu índice.
Essa elegante slice!(0)deve realmente ser a resposta selecionada, pois usar asdf[0] = '' para remover o primeiro caractere é ridículo (assim como usar gsub com regex e disparar uma mosca com um obus).
F055 15/03/16
1
Embora possa parecer pouco intuitivo na superfície, []=não requer tanto código C subjacente, onde slice!requer trabalho adicional. Isso acrescenta-se. O argumento pode ser "Qual é mais legível?" Acho que usar []=legível, mas estou vindo de um plano de fundo C -> Perl que provavelmente colore meu pensamento. Os desenvolvedores de Java provavelmente acham que é menos legível. Uma das maneiras é aceitável para realizar a tarefa, desde que seja fácil de entender e manter e não carregue a CPU indevidamente.
the Tin Man
Está bem. Você sabe como podemos medir se uma função leva muita carga de CPU no ROR? ou devemos usar a diferença de tempo de execução em mili ou nanossegundos?
balanv
18
Ruby 2.5+
A partir do Ruby 2.5, você pode usar delete_prefixou delete_prefix!conseguir isso de maneira legível.
Usando a configuração de benchmark do Tin Man, parece muito rápido também (nas duas últimas entradas delete_pe delete_p!). Não dá muito certo aos favoritos anteriores por velocidade, embora seja muito legível.
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)
Eu usaria em "[12,23,987,43".sub(/^\[+/, "")vez de gsub(/^\[/, ""). O primeiro permite que o mecanismo regex encontre todas as correspondências e, em seguida, elas são substituídas em uma ação e resulta em uma melhoria de velocidade em 2x com o Ruby 1.9.3.
the Tin Man
1
Já que estamos lidando com strings, deveria ser isso 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"
Dessa maneira, você pode remover um por um primeiro caractere da sequência.
Se você quiser preservar a semântica "chop", você pode:"[12,23,987,43".reverse.chop.reverse
Chris Heald
que é um muito grande sobrecarga de desempenho para apenas uma tira de char
Pablo Fernandez
7
por que não usar [1 ..- 1] em vez de [1..self.length]?
horseyguy 01/09/10
O exemplo de conserto de macacos é bastante interessante para esta questão, é apenas IMO irrelevante e feio.
Dredezubov 17/03/2014
3
Agradecemos a @ the-tin-man por reunir os benchmarks!
Infelizmente, eu realmente não gosto de nenhuma dessas soluções. Eles exigem uma etapa extra para obter o resultado ( [0] = '', .strip!) ou não são muito semânticos / claros sobre o que está acontecendo ( [1..-1]: "Hum, um intervalo de 1 a 1 negativo? Anog?"), Ou são lentos ou longos para escreva ( .gsub, .length).
O que estamos tentando é uma 'mudança' (na linguagem Array), mas retornando os caracteres restantes, em vez do que foi mudado. Vamos usar nosso Ruby para tornar isso possível com strings! Podemos usar a operação rápida do suporte, mas dê um bom nome a ela e use um argumento para especificar quanto queremos extrair da frente:
Mas há mais que podemos fazer com essa operação de suporte rápido, mas difícil de manejar. Enquanto estamos nisso, para completar, vamos escrever um #shifte #firstpara String (por que Array deve ter toda a diversão‽‽), usando um argumento para especificar quantos caracteres queremos remover desde o início:
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
Ok, agora temos uma boa maneira clara de extrair caracteres da frente de uma string, com um método que seja consistente com Array#firste Array#shift(que realmente deve ser um método de estrondo ??). E também podemos obter facilmente a string modificada #eat!. Hum, devemos compartilhar nosso novo eat!poder com o Array? Por que não!
É importante notar que isso só funcionará no Ruby 1.9. No Ruby 1.8, isso removerá o primeiro byte da string, não o primeiro caractere, que não é o que o OP deseja.
Jörg W Mittag
0
classStringdef bye_felicia()
felicia =self.strip[0]#first char, not first space.self.sub(felicia,'')endend
delete_prefix
edelete_prefix!
- mais detalhes abaixo . Ainda não tive tempo de avaliar, mas o farei em breve!delete_prefix
\delete_prefix!
) e eles são bem rápidos. Eles não são exatamente os favoritos anteriores em termos de velocidade, mas a legibilidade significa que são ótimas novas opções!Respostas:
Eu meio que gosto de usar algo como:
Estou sempre procurando a maneira mais rápida e legível de fazer as coisas:
Executando no meu Mac Pro:
Atualizando para incorporar mais uma resposta sugerida:
O que resulta em:
E outro usando
/^./
para encontrar o primeiro caractere:O que resulta em:
Aqui está outra atualização de hardware mais rápido e uma versão mais recente do Ruby:
Depois de fazer uma pesquisa / substituição,
gsub
é necessário verificar possíveis correspondências adicionais antes de saber se está finalizado.sub
só faz um e termina. Consideregsub
um mínimo de duassub
chamadas.Além disso, é importante lembrar que
gsub
, esub
também pode ser prejudicado por regex mal escrito que corresponder muito mais lentamente do que uma busca sub-string. Se possível, ancore o regex para obter o máximo de velocidade dele. Há respostas aqui no Stack Overflow demonstrando que, então, procure se deseja mais informações.fonte
"[12,23,987,43".delete "["
what about "[12,23,987,43".shift ?
"? E quanto a"[12,23,987,43".shift NoMethodError: undefined method
shift 'for "[12,23,987,43": String`?Semelhante à resposta de Pablo acima, mas um limpador de sombra:
Retornará a matriz de 1 até o último caractere.
fonte
str[1,]
comparado com o acima?str[1,]
retorna o segundo caractere, pois o intervalo é1:nil
. Você precisaria fornecer o comprimento calculado real ou algo garantido para ser maior que o comprimento, comostr[1,999999]
(use int_max, é claro) para obter a cauda inteira.[1..-1]
é mais limpo e provavelmente mais rápido, já que você não precisa para operar no comprimento manualmente (veja [1..length] no benchmark)str[1..-2]
Podemos usar a fatia para fazer isso:
Usando
slice!
podemos excluir qualquer caractere especificando seu índice.fonte
slice!(0)
deve realmente ser a resposta selecionada, pois usarasdf[0] = ''
para remover o primeiro caractere é ridículo (assim como usar gsub com regex e disparar uma mosca com um obus).[]=
não requer tanto código C subjacente, ondeslice!
requer trabalho adicional. Isso acrescenta-se. O argumento pode ser "Qual é mais legível?" Acho que usar[]=
legível, mas estou vindo de um plano de fundo C -> Perl que provavelmente colore meu pensamento. Os desenvolvedores de Java provavelmente acham que é menos legível. Uma das maneiras é aceitável para realizar a tarefa, desde que seja fácil de entender e manter e não carregue a CPU indevidamente.Ruby 2.5+
A partir do Ruby 2.5, você pode usar
delete_prefix
oudelete_prefix!
conseguir isso de maneira legível.Nesse caso
"[12,23,987,43".delete_prefix("[")
.Mais informações aqui:
Documentos oficiais
https://blog.jetbrains.com/ruby/2017/10/10-new-features-in-ruby-2-5/
https://bugs.ruby-lang.org/issues/12694
NB, você também pode usá-lo para remover itens do final de uma string com
delete_suffix
edelete_suffix!
Editar:
Usando a configuração de benchmark do Tin Man, parece muito rápido também (nas duas últimas entradas
delete_p
edelete_p!
). Não dá muito certo aos favoritos anteriores por velocidade, embora seja muito legível.fonte
Eu prefiro isso:
fonte
Se você sempre deseja remover os colchetes à esquerda:
Se você apenas deseja remover o primeiro caractere e sabe que ele não estará em um conjunto de caracteres multibyte:
ou
fonte
"[12,23,987,43".sub(/^\[+/, "")
vez degsub(/^\[/, "")
. O primeiro permite que o mecanismo regex encontre todas as correspondências e, em seguida, elas são substituídas em uma ação e resulta em uma melhoria de velocidade em 2x com o Ruby 1.9.3.gsub(/\A\[/, "")
?Alternativa ineficiente:
fonte
Por exemplo: a = "One Two Three"
Dessa maneira, você pode remover um por um primeiro caractere da sequência.
fonte
Jeito fácil:
Maneira impressionante:
(Nota: prefira o caminho mais fácil :))
fonte
"[12,23,987,43".reverse.chop.reverse
Agradecemos a @ the-tin-man por reunir os benchmarks!
Infelizmente, eu realmente não gosto de nenhuma dessas soluções. Eles exigem uma etapa extra para obter o resultado (
[0] = ''
,.strip!
) ou não são muito semânticos / claros sobre o que está acontecendo ([1..-1]
: "Hum, um intervalo de 1 a 1 negativo? Anog?"), Ou são lentos ou longos para escreva (.gsub
,.length
).O que estamos tentando é uma 'mudança' (na linguagem Array), mas retornando os caracteres restantes, em vez do que foi mudado. Vamos usar nosso Ruby para tornar isso possível com strings! Podemos usar a operação rápida do suporte, mas dê um bom nome a ela e use um argumento para especificar quanto queremos extrair da frente:
Mas há mais que podemos fazer com essa operação de suporte rápido, mas difícil de manejar. Enquanto estamos nisso, para completar, vamos escrever um
#shift
e#first
para String (por que Array deve ter toda a diversão‽‽), usando um argumento para especificar quantos caracteres queremos remover desde o início:Ok, agora temos uma boa maneira clara de extrair caracteres da frente de uma string, com um método que seja consistente com
Array#first
eArray#shift
(que realmente deve ser um método de estrondo ??). E também podemos obter facilmente a string modificada#eat!
. Hum, devemos compartilhar nosso novoeat!
poder com o Array? Por que não!Agora podemos:
Isso é melhor!
fonte
chip()
vez dechop()
(echimp()
como o análogo dechomp()
).fonte
fonte
Usando regex:
fonte
Acho uma boa solução
str.delete(str[0])
sua legibilidade, embora não possa atestar seu desempenho.fonte
Lista elimina um ou mais elementos desde o início da matriz, não modifica a matriz e retorna a própria matriz em vez do elemento descartado.
fonte