J'ai modifié ma réponse, il est donc possible de modifier la réponse sélectionnée. Voyez si vous pouvez l'attribuer à la réponse de Jason Stirk puisque la sienne est la plus rapide et est très lisible.
the Tin Man
3
Utilisez str [1 ..- 1], son plus rapide selon les réponses ci-dessous.
Achyut Rastogi le
1
À partir de Ruby 2.5, vous pouvez utiliser delete_prefixet delete_prefix!- plus de détails ci-dessous . Je n'ai pas eu le temps de faire des benchmarks, mais je le ferai bientôt!
SRack
Mise à jour: j'ai comparé les nouvelles méthodes ( delete_prefix\ delete_prefix!) et elles sont assez rapides. Ce n'est pas tout à fait le cas des favoris précédents pour la vitesse, mais la lisibilité signifie que ce sont de nouvelles options intéressantes à avoir!
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)
Mise à jour pour incorporer une autre réponse suggérée:
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)
Et un autre utilisant /^./pour trouver le premier caractère:
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.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)
Pourquoi gsub est-il si lent?
Après avoir effectué une recherche / remplacement, gsubdoit vérifier d'éventuelles correspondances supplémentaires avant de pouvoir dire si c'est terminé. subn'en fait qu'un et se termine. Considérez gsubque c'est un minimum de deux subappels.
En outre, il est important de se souvenir de cela gsub, et subpeut également être handicapé par une expression régulière mal écrite qui correspond beaucoup plus lentement qu'une recherche de sous-chaîne. Si possible, ancrez l'expression régulière pour en tirer le maximum de vitesse. Il y a des réponses ici sur Stack Overflow démontrant cela, alors cherchez si vous voulez plus d'informations.
Il est important de noter que cela ne fonctionnera que dans Ruby 1.9. Dans Ruby 1.8, cela supprimera le premier octet de la chaîne, pas le premier caractère, ce qui n'est pas ce que veut l'OP.
Jörg W Mittag
+1: J'oublie toujours qu'à une position de chaîne, vous pouvez attribuer non seulement un seul caractère, mais aussi insérer une sous-chaîne. Merci!
quetzalcoatl
"[12,23,987,43".delete "["
rupweb
4
Cela le supprime de toutes les positions, ce qui n'est pas ce que voulait l'OP: "... pour le premier caractère?".
the Tin Man
2
" what about "[12,23,987,43".shift ?"? Qu'en est-il de "[12,23,987,43".shift NoMethodError: undefined method shift 'pour "[12,23,987,43": String`?
the Tin Man
293
Similaire à la réponse de Pablo ci-dessus, mais un nettoyeur d'ombre:
+1 Jetez un œil aux résultats de référence que j'ai ajoutés à ma réponse. Vous avez le temps d'exécution le plus rapide, et je pense que c'est très propre.
the Tin Man
Qu'en est-il des performances de str[1,]par rapport à celles ci-dessus?
Bohr
1
@Bohr: str[1,]vous renvoie le 2ème caractère puisque la plage est 1:nil. Vous devez fournir la longueur calculée réelle, ou quelque chose qui est garanti supérieur à length, comme, str[1,999999](utilisez int_max bien sûr) pour obtenir la queue entière. [1..-1]est plus propre et probablement plus rapide, car vous n'avez pas besoin d'opérer manuellement sur la longueur (voir [1..length] dans le benchmark)
quetzalcoatl
4
Très belle solution. Au fait si l'on veut supprimer les premier et dernier caractères:str[1..-2]
pisaruk
50
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.
Cet élégant slice!(0)devrait vraiment être la réponse choisie, car utiliser asdf[0] = '' pour supprimer le premier caractère est ridicule (tout comme utiliser gsub avec regex et tirer une mouche avec un obusier).
f055
1
Bien que cela puisse sembler peu intuitif en surface, []=cela ne nécessite pas autant de code C sous-jacent, ce qui slice!nécessite un travail supplémentaire. Cela ajoute. L'argument pourrait être "Lequel est le plus lisible?" Je trouve l'utilisation []=lisible, mais je viens d'un fond 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'elle est facilement compréhensible et maintenable et qu'elle ne charge pas indûment le processeur.
the Tin Man
D'accord. Savez-vous comment nous pouvons mesurer si une fonction prend beaucoup de charge CPU dans ROR? ou devrions-nous utiliser la différence de temps d'exécution en milli ou nanosecondes?
balanv
18
Ruby 2.5+
Depuis Ruby 2.5, vous pouvez utiliser delete_prefixou delete_prefix!pour y parvenir de manière lisible.
En utilisant la configuration de référence de Tin Man, cela semble assez rapide aussi (sous les deux dernières entrées delete_pet delete_p!). Ne fait pas tout à fait pipi les favoris précédents pour la vitesse, bien qu'il soit très lisible.
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)
J'utiliserais à la "[12,23,987,43".sub(/^\[+/, "")place de gsub(/^\[/, ""). Le premier permet au moteur de regex de trouver toutes les correspondances, puis ils sont remplacés en une seule action et entraînent une amélioration de la vitesse d'environ 2x avec Ruby 1.9.3.
the Tin Man
1
Puisque nous avons affaire à des chaînes, est-ce que cela devrait être 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 cette façon, vous pouvez supprimer un par un premier caractère de la chaîne.
Si vous voulez conserver la sémantique "chop", vous pouvez simplement"[12,23,987,43".reverse.chop.reverse
Chris Heald
c'est une assez grosse surcharge de performance juste pour dépouiller un caractère
Pablo Fernandez
7
pourquoi ne pas utiliser [1 ..- 1] plutôt que [1..self.length]?
horseyguy
L'exemple de correctif de singe est assez faux pour cette question, il est juste hors de propos et laid IMO.
dredozubov
3
Merci à @ the-tin-man pour avoir rassemblé les benchmarks!
Hélas, je n'aime vraiment aucune de ces solutions. Soit ils nécessitent une étape supplémentaire pour obtenir le résultat ( [0] = '', .strip!), soit ils ne sont pas très sémantiques / clairs sur ce qui se passe ( [1..-1]: "Um, une plage de 1 à moins 1? Yearg?"), Ou ils sont lents ou longs à écrire ( .gsub, .length).
Ce que nous essayons est un «décalage» (dans le langage Array), mais renvoyant les caractères restants, plutôt que ce qui a été décalé. Utilisons notre Ruby pour rendre cela possible avec des chaînes! Nous pouvons utiliser l'opération de support rapide, mais donnez-lui un bon nom et prenez un argument pour spécifier à quel point nous voulons grignoter le front:
Mais nous pouvons faire plus avec cette opération de support rapide mais peu maniable. Pendant que nous y sommes, pour être complet, écrivons un #shiftet #firstpour String (pourquoi Array devrait-il avoir tout le plaisir?), En prenant un argument pour spécifier le nombre de caractères que nous voulons supprimer depuis le début:
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, maintenant nous avons un bon moyen clair de retirer des caractères au début d'une chaîne, avec une méthode cohérente avec Array#firstet Array#shift(qui devrait vraiment être une méthode bang ??). Et nous pouvons facilement obtenir la chaîne modifiée avec #eat!. Hum, devrions-nous partager notre nouvelle eat!puissance avec Array? Pourquoi pas!
Je me souviens d'une discussion il y a des années dans les forums Perl à propos d'une telle fonction avec le nom de chip()au lieu de chop()(et chimp()comme l'analogue de chomp()).
Il est important de noter que cela ne fonctionnera que dans Ruby 1.9. Dans Ruby 1.8, cela supprimera le premier octet de la chaîne, pas le premier caractère, ce qui n'est pas ce que veut l'OP.
Jörg W Mittag
0
classStringdef bye_felicia()
felicia =self.strip[0]#first char, not first space.self.sub(felicia,'')endend
delete_prefix
etdelete_prefix!
- plus de détails ci-dessous . Je n'ai pas eu le temps de faire des benchmarks, mais je le ferai bientôt!delete_prefix
\delete_prefix!
) et elles sont assez rapides. Ce n'est pas tout à fait le cas des favoris précédents pour la vitesse, mais la lisibilité signifie que ce sont de nouvelles options intéressantes à avoir!Réponses:
Je préfère utiliser quelque chose comme:
Je suis toujours à la recherche de la manière la plus rapide et la plus lisible de faire les choses:
Exécution sur mon Mac Pro:
Mise à jour pour incorporer une autre réponse suggérée:
Ce qui se traduit par:
Et un autre utilisant
/^./
pour trouver le premier caractère:Ce qui se traduit par:
Voici une autre mise à jour sur un matériel plus rapide et une version plus récente de Ruby:
Après avoir effectué une recherche / remplacement,
gsub
doit vérifier d'éventuelles correspondances supplémentaires avant de pouvoir dire si c'est terminé.sub
n'en fait qu'un et se termine. Considérezgsub
que c'est un minimum de deuxsub
appels.En outre, il est important de se souvenir de cela
gsub
, etsub
peut également être handicapé par une expression régulière mal écrite qui correspond beaucoup plus lentement qu'une recherche de sous-chaîne. Si possible, ancrez l'expression régulière pour en tirer le maximum de vitesse. Il y a des réponses ici sur Stack Overflow démontrant cela, alors cherchez si vous voulez plus d'informations.la source
"[12,23,987,43".delete "["
what about "[12,23,987,43".shift ?
"? Qu'en est-il de"[12,23,987,43".shift NoMethodError: undefined method
shift 'pour "[12,23,987,43": String`?Similaire à la réponse de Pablo ci-dessus, mais un nettoyeur d'ombre:
Renvoie le tableau de 1 au dernier caractère.
la source
str[1,]
par rapport à celles ci-dessus?str[1,]
vous renvoie le 2ème caractère puisque la plage est1:nil
. Vous devez fournir la longueur calculée réelle, ou quelque chose qui est garanti supérieur à length, comme,str[1,999999]
(utilisez int_max bien sûr) pour obtenir la queue entière.[1..-1]
est plus propre et probablement plus rapide, car vous n'avez pas besoin d'opérer manuellement sur la longueur (voir [1..length] dans le benchmark)str[1..-2]
Nous pouvons utiliser slice pour faire ceci:
En utilisant,
slice!
nous pouvons supprimer n'importe quel caractère en spécifiant son index.la source
slice!(0)
devrait vraiment être la réponse choisie, car utiliserasdf[0] = ''
pour supprimer le premier caractère est ridicule (tout comme utiliser gsub avec regex et tirer une mouche avec un obusier).[]=
cela ne nécessite pas autant de code C sous-jacent, ce quislice!
nécessite un travail supplémentaire. Cela ajoute. L'argument pourrait être "Lequel est le plus lisible?" Je trouve l'utilisation[]=
lisible, mais je viens d'un fond 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'elle est facilement compréhensible et maintenable et qu'elle ne charge pas indûment le processeur.Ruby 2.5+
Depuis Ruby 2.5, vous pouvez utiliser
delete_prefix
oudelete_prefix!
pour y parvenir de manière lisible.Dans ce cas
"[12,23,987,43".delete_prefix("[")
.Plus d'infos ici:
Documents officiels
https://blog.jetbrains.com/ruby/2017/10/10-new-features-in-ruby-2-5/
https://bugs.ruby-lang.org/issues/12694
NB vous pouvez également l'utiliser pour supprimer des éléments de la fin d'une chaîne avec
delete_suffix
etdelete_suffix!
Éditer:
En utilisant la configuration de référence de Tin Man, cela semble assez rapide aussi (sous les deux dernières entrées
delete_p
etdelete_p!
). Ne fait pas tout à fait pipi les favoris précédents pour la vitesse, bien qu'il soit très lisible.la source
Je préfère ça:
la source
Si vous souhaitez toujours supprimer les crochets de début:
Si vous souhaitez simplement supprimer le premier caractère et que vous savez qu'il ne sera pas dans un jeu de caractères multi-octets:
ou
la source
"[12,23,987,43".sub(/^\[+/, "")
place degsub(/^\[/, "")
. Le premier permet au moteur de regex de trouver toutes les correspondances, puis ils sont remplacés en une seule action et entraînent une amélioration de la vitesse d'environ 2x avec Ruby 1.9.3.gsub(/\A\[/, "")
?Alternative inefficace:
la source
Par exemple: a = "One Two Three"
De cette façon, vous pouvez supprimer un par un premier caractère de la chaîne.
la source
Moyen facile:
Manière géniale:
(Remarque: préférez le moyen facile :))
la source
"[12,23,987,43".reverse.chop.reverse
Merci à @ the-tin-man pour avoir rassemblé les benchmarks!
Hélas, je n'aime vraiment aucune de ces solutions. Soit ils nécessitent une étape supplémentaire pour obtenir le résultat (
[0] = ''
,.strip!
), soit ils ne sont pas très sémantiques / clairs sur ce qui se passe ([1..-1]
: "Um, une plage de 1 à moins 1? Yearg?"), Ou ils sont lents ou longs à écrire (.gsub
,.length
).Ce que nous essayons est un «décalage» (dans le langage Array), mais renvoyant les caractères restants, plutôt que ce qui a été décalé. Utilisons notre Ruby pour rendre cela possible avec des chaînes! Nous pouvons utiliser l'opération de support rapide, mais donnez-lui un bon nom et prenez un argument pour spécifier à quel point nous voulons grignoter le front:
Mais nous pouvons faire plus avec cette opération de support rapide mais peu maniable. Pendant que nous y sommes, pour être complet, écrivons un
#shift
et#first
pour String (pourquoi Array devrait-il avoir tout le plaisir?), En prenant un argument pour spécifier le nombre de caractères que nous voulons supprimer depuis le début:Ok, maintenant nous avons un bon moyen clair de retirer des caractères au début d'une chaîne, avec une méthode cohérente avec
Array#first
etArray#shift
(qui devrait vraiment être une méthode bang ??). Et nous pouvons facilement obtenir la chaîne modifiée avec#eat!
. Hum, devrions-nous partager notre nouvelleeat!
puissance avec Array? Pourquoi pas!Maintenant nous pouvons:
C'est mieux!
la source
chip()
au lieu dechop()
(etchimp()
comme l'analogue dechomp()
).la source
la source
Utilisation de regex:
la source
Je trouve une bonne solution
str.delete(str[0])
pour sa lisibilité, même si je ne peux pas attester de ses performances.la source
List supprime un ou plusieurs éléments depuis le début du tableau, ne mute pas le tableau et renvoie le tableau lui-même au lieu de l'élément déposé.
la source