Beispiel:
[12,23,987,43
Was ist der schnellste und effizienteste Weg, um "[
" Zu entfernen, indem Sie vielleicht ein chop()
verwenden, aber für das erste Zeichen?
Ich bevorzuge mit etwas wie:
asdf = "[12,23,987,43" asdf [0] = '' p asdf # >> "12, 23.987,43 "
Ich bin immer auf der Suche nach der schnellsten und lesbarsten Methode:
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
Laufen auf meinem 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)
Aktualisierung, um eine weitere vorgeschlagene Antwort aufzunehmen:
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
Was in ... endet:
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)
Und eine andere mit /^./
um das erste Zeichen zu finden:
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
Was in ... endet:
# >> 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)
Hier ist ein weiteres Update für schnellere Hardware und eine neuere Version von 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)
Warum ist gsub so langsam?
Nach dem Suchen/Ersetzen muss gsub
nach möglichen zusätzlichen Übereinstimmungen suchen, bevor festgestellt werden kann, ob die Suche abgeschlossen ist. sub
macht nur einen und endet. Betrachten Sie gsub
als wären es mindestens zwei sub
Aufrufe.
Beachten Sie auch, dass gsub
und sub
auch durch schlecht geschriebene reguläre Ausdrücke beeinträchtigt werden können, die viel langsamer als eine Teilstringsuche übereinstimmen. Wenn möglich, verankern Sie den Regex, um die maximale Geschwindigkeit zu erzielen. Hier auf Stack Overflow finden Sie Antworten, die zeigen, dass Sie nach weiteren Informationen suchen müssen.
Ähnlich wie Pablos Antwort oben, aber ein Schattenreiniger:
str[1..-1]
Gibt das Array von 1 bis zum letzten Zeichen zurück.
'Hello World'[1..-1]
=> "Ello World"
Wir können slice verwenden, um dies zu tun:
val = "abc"
=> "abc"
val.slice!(0)
=> "a"
val
=> "bc"
Mit slice!
Wir können jedes Zeichen löschen, indem wir seinen Index angeben.
Ich bevorzuge das:
str = "[12,23,987,43"
puts str[1..-1]
>> 12,23,987,43
Wenn Sie immer führende Klammern entfernen möchten:
"[12,23,987,43".gsub(/^\[/, "")
Wenn Sie nur das erste Zeichen entfernen möchten und wissen, dass es nicht in einem Multibyte-Zeichensatz enthalten ist:
"[12,23,987,43"[1..-1]
oder
"[12,23,987,43".slice(1..-1)
Ab Ruby 2.5 können Sie delete_prefix
Oder delete_prefix!
Verwenden, um dies lesbar zu machen.
In diesem Fall "[12,23,987,43".delete_prefix("[")
.
Mehr Infos hier:
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. Sie können dies auch verwenden, um Elemente mit delete_suffix
und delete_suffix!
vom Ende einer Zeichenfolge zu entfernen.
'worked'.delete_suffix('ed') #=> "work"
'medical'.delete_suffix('ed') #=> "medical"
https://bugs.Ruby-lang.org/issues/13665
Bearbeiten:
Mit dem Benchmark-Setup des Tin Man sieht es auch ziemlich schnell aus (unter den letzten beiden Einträgen delete_p
Und delete_p!
). Pipe ganz die vorherigen Favoriten für die Geschwindigkeit, obwohl sehr gut lesbar ist.
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)
Ineffiziente Alternative:
str.reverse.chop.reverse
Zum Beispiel: a = "Eins Zwei Drei"
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"
Auf diese Weise können Sie ein einzelnes erstes Zeichen der Zeichenfolge entfernen.
Vielen Dank an @ the-tin-man für die Zusammenstellung der Benchmarks!
Leider mag ich keine dieser Lösungen wirklich. Entweder benötigen sie einen zusätzlichen Schritt, um das Ergebnis zu erhalten ([0] = ''
, .strip!
), Oder sie wissen nicht genau, was passiert ([1..-1]
: "Ähm, ein Bereich von 1 bis negativ 1? Yearg? "), oder sie sind langsam oder langwierig zu schreiben (.gsub
, .length
).
Was wir versuchen, ist eine „Verschiebung“ (in der Array-Sprache), die jedoch die verbleibenden Zeichen zurückgibt, anstatt die verschobenen Zeichen. Verwenden wir unser Ruby), um dies mit Strings zu ermöglichen! Wir können die schnelle Klammeroperation verwenden, aber einen guten Namen vergeben und ein Argument verwenden, um anzugeben, wie viel wir von der Vorderseite abschneiden möchten :
class String
def eat!(how_many = 1)
self.replace self[how_many..-1]
end
end
Mit dieser schnellen, aber unhandlichen Bracket-Operation können wir jedoch noch mehr tun. Schreiben wir der Vollständigkeit halber #shift
Und #first
Für String (warum sollte Array den ganzen Spaß haben?), Und geben Sie mit einem Argument an, wie viele Zeichen wir wollen vom anfang entfernen:
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, jetzt haben wir eine gute Möglichkeit, Zeichen von der Vorderseite eines Strings abzuziehen, mit einer Methode, die mit Array#first
Und Array#shift
Konsistent ist (die eigentlich eine Knallmethode sein sollte ??) . Und wir können den modifizierten String auch mit #eat!
Leicht bekommen. Hm, sollten wir unsere neue eat!
- Kraft mit Array teilen? Warum nicht!
class Array
def eat!(how_many = 1)
self.replace self[how_many..-1]
end
end
Jetzt können wir:
> 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]
Das ist besser!
Einfacher Weg:
str = "[12,23,987,43"
removed = str[1..str.length]
Genialer Weg:
class String
def reverse_chop()
self[1..self.length]
end
end
"[12,23,987,43".reverse_chop()
(Hinweis: lieber einfach :))
str = "[12,23,987,43"
str[0] = ""
list = [1,2,3,4] list.drop (1)
# => [2,3,4]
List löscht ein oder mehrere Elemente am Anfang des Arrays, verändert das Array nicht und gibt das Array selbst anstelle des gelöschten Elements zurück.
class String
def bye_felicia()
felicia = self.strip[0] #first char, not first space.
self.sub(felicia, '')
end
end
Regex verwenden:
str = 'string'
n = 1 #to remove first n characters
str[/.{#{str.size-n}}\z/] #=> "tring"
Ich finde, dass eine gute Lösung wegen ihrer Lesbarkeit str.delete(str[0])
ist, obwohl ich nicht bezeugen kann, dass sie funktioniert.