Quelle est la façon la plus simple de supprimer le premier caractère d'une chaîne?
exemple:
[12,23,987,43
Quel est le moyen le plus rapide et le plus efficace pour supprimer le " [
",
en utilisant peut-être un chop()
mais pour le premier caractère?
15 réponses
j'ai une sorte de faveur en utilisant quelque chose comme:
asdf = "[12,23,987,43" asdf[0] = '' p asdf # >> "12,23,987,43"
je suis toujours à la recherche de la façon la plus rapide et la plus lisible de faire les choses:
require 'benchmark'
N = 1_000_000
puts RUBY_VERSION
STR = "[12,23,987,43"
Benchmark.bm(7) do |b|
b.report('[0]') { N.times { "[12,23,987,43"[0] = '' } }
b.report('sub') { N.times { "[12,23,987,43".sub(/^\[+/, "") } }
b.report('gsub') { N.times { "[12,23,987,43".gsub(/^\[/, "") } }
b.report('[1..-1]') { N.times { "[12,23,987,43"[1..-1] } }
b.report('slice') { N.times { "[12,23,987,43".slice!(0) } }
b.report('length') { N.times { "[12,23,987,43"[1..STR.length] } }
end
en cours d'Exécution sur mon Mac Pro:
1.9.3
user system total real
[0] 0.840000 0.000000 0.840000 ( 0.847496)
sub 1.960000 0.010000 1.970000 ( 1.962767)
gsub 4.350000 0.020000 4.370000 ( 4.372801)
[1..-1] 0.710000 0.000000 0.710000 ( 0.713366)
slice 1.020000 0.000000 1.020000 ( 1.020336)
length 1.160000 0.000000 1.160000 ( 1.157882)
mise à Jour pour intégrer encore une proposition de réponse:
require 'benchmark'
N = 1_000_000
class String
def eat!(how_many = 1)
self.replace self[how_many..-1]
end
def first(how_many = 1)
self[0...how_many]
end
def shift(how_many = 1)
shifted = first(how_many)
self.replace self[how_many..-1]
shifted
end
alias_method :shift!, :shift
end
class Array
def eat!(how_many = 1)
self.replace self[how_many..-1]
end
end
puts RUBY_VERSION
STR = "[12,23,987,43"
Benchmark.bm(7) do |b|
b.report('[0]') { N.times { "[12,23,987,43"[0] = '' } }
b.report('sub') { N.times { "[12,23,987,43".sub(/^\[+/, "") } }
b.report('gsub') { N.times { "[12,23,987,43".gsub(/^\[/, "") } }
b.report('[1..-1]') { N.times { "[12,23,987,43"[1..-1] } }
b.report('slice') { N.times { "[12,23,987,43".slice!(0) } }
b.report('length') { N.times { "[12,23,987,43"[1..STR.length] } }
b.report('eat!') { N.times { "[12,23,987,43".eat! } }
b.report('reverse') { N.times { "[12,23,987,43".reverse.chop.reverse } }
end
qui se traduit par:
2.1.2
user system total real
[0] 0.300000 0.000000 0.300000 ( 0.295054)
sub 0.630000 0.000000 0.630000 ( 0.631870)
gsub 2.090000 0.000000 2.090000 ( 2.094368)
[1..-1] 0.230000 0.010000 0.240000 ( 0.232846)
slice 0.320000 0.000000 0.320000 ( 0.320714)
length 0.340000 0.000000 0.340000 ( 0.341918)
eat! 0.460000 0.000000 0.460000 ( 0.452724)
reverse 0.400000 0.000000 0.400000 ( 0.399465)
Et un autre à l'aide de /^./
pour trouver le premier caractère:
require 'benchmark'
N = 1_000_000
class String
def eat!(how_many = 1)
self.replace self[how_many..-1]
end
def first(how_many = 1)
self[0...how_many]
end
def shift(how_many = 1)
shifted = first(how_many)
self.replace self[how_many..-1]
shifted
end
alias_method :shift!, :shift
end
class Array
def eat!(how_many = 1)
self.replace self[how_many..-1]
end
end
puts RUBY_VERSION
STR = "[12,23,987,43"
Benchmark.bm(7) do |b|
b.report('[0]') { N.times { "[12,23,987,43"[0] = '' } }
b.report('[/^./]') { N.times { "[12,23,987,43"[/^./] = '' } }
b.report('[/^\[/]') { N.times { "[12,23,987,43"[/^\[/] = '' } }
b.report('sub+') { N.times { "[12,23,987,43".sub(/^\[+/, "") } }
b.report('sub') { N.times { "[12,23,987,43".sub(/^\[/, "") } }
b.report('gsub') { N.times { "[12,23,987,43".gsub(/^\[/, "") } }
b.report('[1..-1]') { N.times { "[12,23,987,43"[1..-1] } }
b.report('slice') { N.times { "[12,23,987,43".slice!(0) } }
b.report('length') { N.times { "[12,23,987,43"[1..STR.length] } }
b.report('eat!') { N.times { "[12,23,987,43".eat! } }
b.report('reverse') { N.times { "[12,23,987,43".reverse.chop.reverse } }
end
qui se traduit par:
# >> 2.1.5
# >> user system total real
# >> [0] 0.270000 0.000000 0.270000 ( 0.270165)
# >> [/^./] 0.430000 0.000000 0.430000 ( 0.432417)
# >> [/^\[/] 0.460000 0.000000 0.460000 ( 0.458221)
# >> sub+ 0.590000 0.000000 0.590000 ( 0.590284)
# >> sub 0.590000 0.000000 0.590000 ( 0.596366)
# >> gsub 1.880000 0.010000 1.890000 ( 1.885892)
# >> [1..-1] 0.230000 0.000000 0.230000 ( 0.223045)
# >> slice 0.300000 0.000000 0.300000 ( 0.299175)
# >> length 0.320000 0.000000 0.320000 ( 0.325841)
# >> eat! 0.410000 0.000000 0.410000 ( 0.409306)
# >> reverse 0.390000 0.000000 0.390000 ( 0.393044)
voici une autre mise à jour sur le matériel plus rapide et une nouvelle version de Ruby:
2.3.1
user system total real
[0] 0.200000 0.000000 0.200000 ( 0.204307)
[/^./] 0.390000 0.000000 0.390000 ( 0.387527)
[/^\[/] 0.360000 0.000000 0.360000 ( 0.360400)
sub+ 0.490000 0.000000 0.490000 ( 0.492083)
sub 0.480000 0.000000 0.480000 ( 0.487862)
gsub 1.990000 0.000000 1.990000 ( 1.988716)
[1..-1] 0.180000 0.000000 0.180000 ( 0.181673)
slice 0.260000 0.000000 0.260000 ( 0.266371)
length 0.270000 0.000000 0.270000 ( 0.267651)
eat! 0.400000 0.010000 0.410000 ( 0.398093)
reverse 0.340000 0.000000 0.340000 ( 0.344077)
pourquoi gsub est-il si lent?
après avoir effectué une recherche/remplacer, gsub
doit vérifiez si d'autres correspondances sont possibles avant de savoir si c'est terminé. sub
ne fait qu'un et finit. Considérez gsub
comme un minimum de deux appels sub
.
aussi, il est important de se rappeler que gsub
, et sub
peuvent également être handicapés par regex mal écrit qui correspondent beaucoup plus lentement qu'une recherche sous-chaîne. Si possible, l'ancrage de la regex pour obtenir le plus de vitesse. Il y a des réponses ici sur le débordement de la pile ce qui démontre que si la recherche autour si vous voulez plus d'informations.
semblable à la réponse de Pablo ci-dessus, mais un nettoyeur d'ombre:
str[1..-1]
renvoie le tableau de 1 au dernier caractère.
'Hello World'[1..-1]
=> "ello World"
nous pouvons utiliser slice pour faire ceci:
val = "abc"
=> "abc"
val.slice!(0)
=> "a"
val
=> "bc"
en utilisant slice!
nous pouvons supprimer n'importe quel caractère en spécifiant son index.
si vous voulez toujours supprimer les crochets avant:
"[12,23,987,43".gsub(/^\[/, "")
Si vous voulez simplement supprimer le premier caractère, et vous savez qu'il ne sera pas dans un jeu de caractères multioctets:
"[12,23,987,43"[1..-1]
ou
"[12,23,987,43".slice(1..-1)
je préfère cette
srt = [12,23,987,43
p srt[1..-1]
>> 12,23,987,43
par exemple: a = "Un Deux Trois "
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 cette façon, vous pouvez supprimer un par un premier caractère de la chaîne.
à partir de Ruby 2.5 vous pouvez utiliser delete_prefix
ou delete_prefix!
pour réaliser ceci d'une manière lisible.
dans ce cas "[12,23,987,43".delete_prefix("[")
.
plus d'informations ici:
https://blog.jetbrains.com/ruby/2017/10/10-new-features-in-ruby-2-5 /
https://bugs.ruby-lang.org/issues/12694
'invisible'.delete_prefix('in') #=> "visible"
'pink'.delete_prefix('in') #=> "pink"
N.B. vous pouvez aussi utilisez ceci pour supprimer des articles de la fin d'une chaîne de caractères avec delete_suffix
et delete_suffix!
'worked'.delete_suffix('ed') #=> "work"
'medical'.delete_suffix('ed') #=> "medical"
https://bugs.ruby-lang.org/issues/13665
Edit:
en utilisant la configuration de référence de Tin Man, il semble assez rapide aussi (sous les deux dernières entrées delete_p
et delete_p!
). Ne pas tout à fait pip de la précédente favoris pour la vitesse, mais est très lisible.
2.5.0
user system total real
[0] 0.174766 0.000489 0.175255 ( 0.180207)
[/^./] 0.318038 0.000510 0.318548 ( 0.323679)
[/^\[/] 0.372645 0.001134 0.373779 ( 0.379029)
sub+ 0.460295 0.001510 0.461805 ( 0.467279)
sub 0.498351 0.001534 0.499885 ( 0.505729)
gsub 1.669837 0.005141 1.674978 ( 1.682853)
[1..-1] 0.199840 0.000976 0.200816 ( 0.205889)
slice 0.279661 0.000859 0.280520 ( 0.285661)
length 0.268362 0.000310 0.268672 ( 0.273829)
eat! 0.341715 0.000524 0.342239 ( 0.347097)
reverse 0.335301 0.000588 0.335889 ( 0.340965)
delete_p 0.222297 0.000832 0.223129 ( 0.228455)
delete_p! 0.225798 0.000747 0.226545 ( 0.231745)
voie Facile:
str = "[12,23,987,43"
removed = str[1..str.length]
Génial": 151930920"
class String
def reverse_chop()
self[1..self.length]
end
end
"[12,23,987,43".reverse_chop()
(Note: préférer la voie de la facilité :) )
merci à @The-tin-man d'avoir assemblé les benchmarks!
hélas, je n'aime pas vraiment aucune de ces solutions. Soit ils nécessitent une étape supplémentaire pour obtenir le résultat ( [0] = ''
, .strip!
) ou ils ne sont pas très sémantique/clair sur ce qui se passe ( [1..-1]
: "Um, une gamme de 1 à négatif 1? Yearg?"), ou ils sont lents ou longs à écrire ( .gsub
, .length
).
ce que nous tentons est un "changement" (en Tableau jargon), mais en retournant les caractères restants, plutôt que ce qui a été décalé. Utilisons notre rubis pour rendre cela possible avec des cordes! Nous pouvons utiliser l'opération rapide bracket, mais lui donner une bonne réputation, et prendre un arg pour préciser combien nous voulons chomp hors de l'avant:
class String
def eat!(how_many = 1)
self.replace self[how_many..-1]
end
end
mais il y a plus que nous pouvons faire avec cette opération rapide-mais-lourde des crochets. Pendant que nous y sommes, par souci d'exhaustivité, écrivons un #shift
et #first
pour chaîne de caractères (pourquoi Array devrait avoir tout le plaisir‽), en prenant un arg pour spécifier le nombre de caractères que nous voulons supprimer dès le début:
class String
def first(how_many = 1)
self[0...how_many]
end
def shift(how_many = 1)
shifted = first(how_many)
self.replace self[how_many..-1]
shifted
end
alias_method :shift!, :shift
end
Ok, maintenant nous avons une bonne façon claire de tirer des caractères sur le devant d'une chaîne, avec une méthode qui est compatible avec Array#first
et Array#shift
(qui devrait vraiment être une méthode de bang??). Et nous pouvons facilement obtenir la chaîne modifiée ainsi avec #eat!
. Devrions-nous partager notre nouveau eat!
avec Array? Pourquoi pas!
class Array
def eat!(how_many = 1)
self.replace self[how_many..-1]
end
end
maintenant nous pouvons:
> str = "[12,23,987,43" #=> "[12,23,987,43"
> str.eat! #=> "12,23,987,43"
> str #=> "12,23,987,43"
> str.eat!(3) #=> "23,987,43"
> str #=> "23,987,43"
> str.first(2) #=> "23"
> str #=> "23,987,43"
> str.shift!(3) #=> "23,"
> str #=> "987,43"
> arr = [1,2,3,4,5] #=> [1, 2, 3, 4, 5]
> arr.eat! #=> [2, 3, 4, 5]
> arr #=> [2, 3, 4, 5]
c'est mieux!
class String
def bye_felicia()
felicia = self.strip[0] #first char, not first space.
self.sub(felicia, '')
end
end
utilisant regex:
str = 'string'
n = 1 #to remove first n characters
str[/.{#{str.size-n}}\z/] #=> "tring"
je trouve une bonne solution d'être str.delete(str[0])
pour sa lisibilité, bien que je ne puisse pas attester de sa performance.
liste = [1,2,3,4] liste.drop (1)
# => [2,3,4]
Liste fait tomber un ou plusieurs éléments du début du tableau, ne mute pas le tableau, et renvoie le tableau lui-même à la place de l'élément abandonné.