Ejemplo:
[12,23,987,43
Quel est le moyen le plus rapide et le plus efficace de supprimer le " [
", en utilisant peut-être un chop()
mais pour le premier personnage ?
Ejemplo:
[12,23,987,43
Quel est le moyen le plus rapide et le plus efficace de supprimer le " [
", en utilisant peut-être un chop()
mais pour le premier personnage ?
+1 Jetez un coup d'œil aux résultats du benchmark que j'ai ajouté à ma réponse. Vous avez le temps d'exécution le plus rapide, et je pense que c'est très propre.
@Bohr : str[1,]
vous renvoie le 2ème caractère puisque la plage est 1:nil
. Vous devez fournir la longueur réelle calculée, ou quelque chose de garanti comme étant supérieur à la longueur, par exemple, str[1,999999]
(utilisez int_max bien sûr) pour obtenir la queue entière. [1..-1]
est plus propre et probablement plus rapide, puisque vous n'avez pas besoin d'opérer sur la longueur manuellement (voir le [1..length] dans le benchmark)
Je préfère utiliser 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
Fonctionne 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 incorporer une réponse supplémentaire suggérée :
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
Ce qui a pour conséquence :
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 utilisant /^./
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
Ce qui a pour conséquence :
# >> 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 un matériel plus rapide et une version plus récente 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 fait une recherche/remplacement, gsub
doit vérifier s'il y a d'autres correspondances possibles avant de savoir s'il a terminé. sub
n'en fait qu'une et termine. Pensez à gsub
comme si c'était un minimum de deux sub
appels.
En outre, il est important de se rappeler que gsub
y sub
peut également être handicapé par des expressions rationnelles mal écrites qui correspondent beaucoup plus lentement qu'une recherche par sous-chaîne. Si possible, ancrez la regex pour en tirer le maximum de vitesse. Il y a des réponses ici sur Stack Overflow qui démontrent cela, alors cherchez si vous voulez plus d'informations.
Il est important de noter que cela ne fonctionne qu'en Ruby 1.9. En Ruby 1.8, cela supprimera le premier élément octet de la chaîne, pas le premier caractère, ce qui n'est pas ce que souhaite le PO.
+1 : I toujours oubliez qu'à une position de chaîne de caractères, vous pouvez non seulement attribuer un caractère unique, mais aussi insérer une sous-chaîne. Merci !
Cet élégant slice!(0)
devrait vraiment être la réponse choisie, car l'utilisation de asdf[0] = ''
pour supprimer le premier caractère est ridicule (tout comme utiliser gsub avec regex et tirer sur une mouche avec un obusier).
Bien que cela puisse sembler peu intuitif à première vue, []=
ne nécessite pas autant de code C sous-jacent, alors que slice!
nécessite un travail supplémentaire. Cela s'ajoute. L'argument pourrait être "Qu'est-ce qui est le plus lisible ?". Je trouve qu'utiliser []=
lisible, mais je viens d'un milieu C --> Perl qui colore probablement ma pensée. Les développeurs Java penseraient probablement que c'est moins lisible. L'un ou l'autre est un moyen acceptable d'accomplir la tâche tant qu'il est facilement compréhensible et maintenable et qu'il ne charge pas indûment le CPU.
Vous pouvez vérifier les autres réponses avant de les répéter. Cela a déjà été suggéré par stackoverflow.com/a/3614642/128421
J'utiliserais "[12,23,987,43".sub(/^\[+/, "")
au lieu de gsub(/^\[/, "")
. La première permet au moteur d'expressions rationnelles de trouver toutes les correspondances et de les remplacer en une seule action. Elle permet de multiplier par deux la vitesse d'exécution avec Ruby 1.9.3.
Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.
1 votes
J'ai modifié ma réponse, il est donc possible de changer la réponse que vous avez choisie. Voyez si vous pouvez l'attribuer à la réponse de Jason Stirk car la sienne est la plus rapide et est très lisible.
3 votes
Utilisez str[1..-1], c'est le plus rapide selon les réponses ci-dessous.
1 votes
À partir de Ruby 2.5, vous pouvez utiliser
delete_prefix
ydelete_prefix!
- plus de détails ci-dessous . Je n'ai pas eu le temps de faire un benchmark, mais je le ferai bientôt !0 votes
Mise à jour : J'ai testé les nouvelles méthodes (
delete_prefix
\delete_prefix!
) et ils sont assez rapides. Ils ne sont pas aussi rapides que les précédents, mais leur lisibilité en fait de nouvelles options intéressantes !