Ich habe meine Antwort bearbeitet, sodass Sie möglicherweise Ihre ausgewählte Antwort ändern können. Sehen Sie, ob Sie es Jason Stirk's Antwort geben können, da seine die schnellste und gut lesbare ist.
der Blechmann
3
Verwenden Sie str [1 ..- 1], das gemäß den folgenden Antworten am schnellsten ist.
Achyut Rastogi
1
Ab Ruby 2.5 können Sie delete_prefixund delete_prefix!- weitere Details unten verwenden . Ich hatte keine Zeit zum Benchmarking, werde es aber bald tun!
SRack
Update: Ich habe die neuen Methoden ( delete_prefix\ delete_prefix!) verglichen und sie sind ziemlich schnell. Die vorherigen Favoriten sind nicht ganz auf Geschwindigkeit ausgerichtet, aber Lesbarkeit bedeutet, dass sie großartige neue Optionen sind!
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)
Aktualisierung, um eine weitere vorgeschlagene Antwort aufzunehmen:
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)
Und eine andere /^./, um das erste Zeichen zu finden:
Hier ist ein weiteres Update für schnellere Hardware und eine neuere Version von 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)
Warum ist gsub so langsam?
Nach dem Suchen / Ersetzen gsubmuss nach möglichen zusätzlichen Übereinstimmungen gesucht werden, bevor festgestellt werden kann, ob die Suche abgeschlossen ist. submacht nur eins und endet. Stellen gsubSie sich vor, es sind mindestens zwei subAnrufe.
Es ist auch wichtig, sich daran zu erinnern gsub, und es subkann auch durch schlecht geschriebenen regulären Ausdruck behindert werden, der viel langsamer als eine Suche nach Teilzeichenfolgen übereinstimmt. Wenn möglich, verankern Sie den Regex, um die größtmögliche Geschwindigkeit zu erzielen. Hier auf Stack Overflow finden Sie Antworten, die zeigen, dass Sie nach weiteren Informationen suchen müssen.
Es ist wichtig zu beachten, dass dies nur in Ruby 1.9 funktioniert. In Ruby 1.8 wird dadurch das erste Byte aus der Zeichenfolge entfernt, nicht das erste Zeichen, was vom OP nicht gewünscht wird.
Jörg W Mittag
+1: Ich vergesse immer , dass Sie einer String-Position nicht nur ein einzelnes Zeichen zuweisen können, sondern auch einen Teilstring einfügen können. Vielen Dank!
Quetzalcoatl
"[12,23,987,43".delete "["
Rupweb
4
Das löscht es aus allen Positionen, was das OP nicht wollte: "... für das erste Zeichen?".
der Blechmann
2
" what about "[12,23,987,43".shift ?"? Was ist mit "[12,23,987,43".shift NoMethodError: undefined method shift 'für "[12,23,987,43": String`?
der Blechmann
292
Ähnlich wie Pablos Antwort oben, aber ein Schattenreiniger:
str[1..-1]
Gibt das Array von 1 bis zum letzten Zeichen zurück.
+1 Sehen Sie sich die Benchmark-Ergebnisse an, die ich meiner Antwort hinzugefügt habe. Sie haben die schnellste Laufzeit und ich denke, es ist sehr sauber.
der Blechmann
Was ist mit der Leistung von im str[1,]Vergleich zu den oben genannten?
Bohr
1
@Bohr: Gib str[1,]dir das 2. Zeichen zurück, da der Bereich ist 1:nil. Sie müssten die tatsächlich berechnete Länge str[1,999999]angeben oder etwas, das garantiert höher als die Länge ist, wie (verwenden Sie natürlich int_max), um den gesamten Schwanz zu erhalten. [1..-1]ist sauberer und wahrscheinlich schneller, da Sie die Länge nicht manuell bearbeiten müssen (siehe [1..Länge] im Benchmark)
quetzalcoatl
4
Sehr schöne Lösung. Übrigens, wenn man erste und letzte Zeichen entfernen möchte:str[1..-2]
Pisaruk
50
Wir können Slice verwenden, um dies zu tun:
val ="abc"=>"abc"
val.slice!(0)=>"a"
val
=>"bc"
Mit können slice!wir jedes Zeichen löschen, indem wir seinen Index angeben.
Dieses elegante slice!(0)sollte wirklich die ausgewählte Antwort sein, da asdf[0] = '' es lächerlich ist, das erste Zeichen zu entfernen (genau wie gsub mit Regex zu verwenden und eine Fliege mit einer Haubitze zu schießen).
f055
1
Obwohl es auf den ersten Blick []=nicht intuitiv zu sein scheint, erfordert es nicht so viel zugrunde liegenden C-Code, wo slice!zusätzliche Arbeit erforderlich ist. Das summiert sich. Das Argument könnte lauten: "Was ist besser lesbar?" Ich finde die Verwendung []=lesbar, aber ich komme aus einem C -> Perl-Hintergrund, der wahrscheinlich mein Denken beeinflusst. Java-Entwickler würden wahrscheinlich denken, dass es weniger lesbar ist. Beides ist ein akzeptabler Weg, um die Aufgabe zu erfüllen, solange sie leicht verständlich und wartbar ist und die CPU nicht übermäßig belastet.
der Blechmann
OK. Wissen Sie, wie wir messen können, ob eine Funktion in ROR viel CPU-Last beansprucht? oder sollten wir die Ausführungszeitdifferenz in Milli oder Nanosekunden verwenden?
Balanv
18
Ruby 2.5+
Ab Ruby 2.5 können Sie dies lesbar verwenden delete_prefixoder delete_prefix!erreichen.
In diesem Fall "[12,23,987,43".delete_prefix("[").
Mit dem Benchmark-Setup des Tin Man sieht es auch ziemlich schnell aus (unter den letzten beiden Einträgen delete_pund delete_p!). Paspelt die vorherigen Favoriten nicht ganz auf Geschwindigkeit, ist aber sehr gut lesbar.
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)
Ich würde "[12,23,987,43".sub(/^\[+/, "")anstelle von verwenden gsub(/^\[/, ""). Mit der ersten Option kann die Regex-Engine alle Übereinstimmungen finden, dann werden sie in einer Aktion ersetzt und die Geschwindigkeit von Ruby 1.9.3 wird um das Zweifache verbessert.
der Blechmann
1
Sollte dies so sein, da es sich um Strings handelt 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"
Auf diese Weise können Sie nacheinander das erste Zeichen der Zeichenfolge entfernen.
Wenn Sie die "Chop" -Semantik beibehalten möchten, können Sie einfach"[12,23,987,43".reverse.chop.reverse
Chris Heald
Das ist ein ziemlich großer Leistungsaufwand, nur um einen Charakter zu entfernen
Pablo Fernandez
7
Warum nicht [1 ..- 1] anstelle von [1..self.length] verwenden?
Horseyguy
Das Beispiel für das Patchen von Affen ist für diese Frage ziemlich falsch, es ist nur irrelevant und hässlich, IMO.
Dredozubov
3
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 sind nicht sehr semantisch / klar darüber, was passiert ( [1..-1]: "Ähm, ein Bereich von 1 bis negativ 1? Yearg?"), Oder sie sind langsam oder langwierig schreibe aus ( .gsub, .length).
Was wir versuchen, ist eine 'Verschiebung' (im Array-Sprachgebrauch), die jedoch die verbleibenden Zeichen zurückgibt, anstatt das, was verschoben wurde. Verwenden wir unseren Ruby, um dies mit Strings zu ermöglichen! Wir können die schnelle Klammeroperation verwenden, aber geben Sie ihr einen guten Namen und nehmen Sie ein Argument, um anzugeben, wie viel wir von vorne abkauen möchten:
Mit dieser schnellen, aber unhandlichen Klammeroperation können wir jedoch noch mehr tun. Wenn wir gerade dabei sind, schreiben wir der Vollständigkeit halber ein #shiftund #firstfür String (warum sollte Array den ganzen Spaß haben) und nehmen ein Argument, um anzugeben, wie viele Zeichen wir von Anfang an entfernen möchten:
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, jetzt haben wir eine gute Möglichkeit, Zeichen von der Vorderseite eines Strings zu ziehen, mit einer Methode, die mit Array#firstund übereinstimmt Array#shift(was eigentlich eine Knallmethode sein sollte?). Und wir können den modifizierten String auch leicht mit bekommen #eat!. Hm, sollten wir unsere neue eat!Kraft mit Array teilen ? Warum nicht!
Ich erinnere mich an eine Diskussion vor Jahren in Perl-Foren über eine solche Funktion mit dem Namen chip()anstelle von chop()(und chimp()als Analogon von chomp()).
Es ist wichtig zu beachten, dass dies nur in Ruby 1.9 funktioniert. In Ruby 1.8 wird dadurch das erste Byte aus der Zeichenfolge entfernt, nicht das erste Zeichen, was vom OP nicht gewünscht wird.
Jörg W Mittag
0
classStringdef bye_felicia()
felicia =self.strip[0]#first char, not first space.self.sub(felicia,'')endend
List löscht ein oder mehrere Elemente vom Anfang des Arrays, mutiert das Array nicht und gibt das Array selbst anstelle des abgelegten Elements zurück.
delete_prefix
unddelete_prefix!
- weitere Details unten verwenden . Ich hatte keine Zeit zum Benchmarking, werde es aber bald tun!delete_prefix
\delete_prefix!
) verglichen und sie sind ziemlich schnell. Die vorherigen Favoriten sind nicht ganz auf Geschwindigkeit ausgerichtet, aber Lesbarkeit bedeutet, dass sie großartige neue Optionen sind!Antworten:
Ich bevorzuge etwas wie:
Ich bin immer auf der Suche nach der schnellsten und am besten lesbaren Methode:
Laufen auf meinem Mac Pro:
Aktualisierung, um eine weitere vorgeschlagene Antwort aufzunehmen:
Was in ... endet:
Und eine andere
/^./
, um das erste Zeichen zu finden:Was in ... endet:
Hier ist ein weiteres Update für schnellere Hardware und eine neuere Version von Ruby:
Nach dem Suchen / Ersetzen
gsub
muss nach möglichen zusätzlichen Übereinstimmungen gesucht werden, bevor festgestellt werden kann, ob die Suche abgeschlossen ist.sub
macht nur eins und endet. Stellengsub
Sie sich vor, es sind mindestens zweisub
Anrufe.Es ist auch wichtig, sich daran zu erinnern
gsub
, und essub
kann auch durch schlecht geschriebenen regulären Ausdruck behindert werden, der viel langsamer als eine Suche nach Teilzeichenfolgen übereinstimmt. Wenn möglich, verankern Sie den Regex, um die größtmögliche Geschwindigkeit zu erzielen. Hier auf Stack Overflow finden Sie Antworten, die zeigen, dass Sie nach weiteren Informationen suchen müssen.quelle
"[12,23,987,43".delete "["
what about "[12,23,987,43".shift ?
"? Was ist mit"[12,23,987,43".shift NoMethodError: undefined method
shift 'für "[12,23,987,43": String`?Ähnlich wie Pablos Antwort oben, aber ein Schattenreiniger:
Gibt das Array von 1 bis zum letzten Zeichen zurück.
quelle
str[1,]
Vergleich zu den oben genannten?str[1,]
dir das 2. Zeichen zurück, da der Bereich ist1:nil
. Sie müssten die tatsächlich berechnete Längestr[1,999999]
angeben oder etwas, das garantiert höher als die Länge ist, wie (verwenden Sie natürlich int_max), um den gesamten Schwanz zu erhalten.[1..-1]
ist sauberer und wahrscheinlich schneller, da Sie die Länge nicht manuell bearbeiten müssen (siehe [1..Länge] im Benchmark)str[1..-2]
Wir können Slice verwenden, um dies zu tun:
Mit können
slice!
wir jedes Zeichen löschen, indem wir seinen Index angeben.quelle
slice!(0)
sollte wirklich die ausgewählte Antwort sein, daasdf[0] = ''
es lächerlich ist, das erste Zeichen zu entfernen (genau wie gsub mit Regex zu verwenden und eine Fliege mit einer Haubitze zu schießen).[]=
nicht intuitiv zu sein scheint, erfordert es nicht so viel zugrunde liegenden C-Code, woslice!
zusätzliche Arbeit erforderlich ist. Das summiert sich. Das Argument könnte lauten: "Was ist besser lesbar?" Ich finde die Verwendung[]=
lesbar, aber ich komme aus einem C -> Perl-Hintergrund, der wahrscheinlich mein Denken beeinflusst. Java-Entwickler würden wahrscheinlich denken, dass es weniger lesbar ist. Beides ist ein akzeptabler Weg, um die Aufgabe zu erfüllen, solange sie leicht verständlich und wartbar ist und die CPU nicht übermäßig belastet.Ruby 2.5+
Ab Ruby 2.5 können Sie dies lesbar verwenden
delete_prefix
oderdelete_prefix!
erreichen.In diesem Fall
"[12,23,987,43".delete_prefix("[")
.Mehr Infos hier:
Offizielle Dokumente
https://blog.jetbrains.com/ruby/2017/10/10-new-features-in-ruby-2-5/
https://bugs.ruby-lang.org/issues/12694
Hinweis: Sie können dies auch verwenden, um Elemente mit
delete_suffix
und vom Ende einer Zeichenfolge zu entfernendelete_suffix!
Bearbeiten:
Mit dem Benchmark-Setup des Tin Man sieht es auch ziemlich schnell aus (unter den letzten beiden Einträgen
delete_p
unddelete_p!
). Paspelt die vorherigen Favoriten nicht ganz auf Geschwindigkeit, ist aber sehr gut lesbar.quelle
Ich bevorzuge das:
quelle
Wenn Sie immer führende Klammern entfernen möchten:
Wenn Sie nur das erste Zeichen entfernen möchten und wissen, dass es nicht in einem Multibyte-Zeichensatz enthalten ist:
oder
quelle
"[12,23,987,43".sub(/^\[+/, "")
anstelle von verwendengsub(/^\[/, "")
. Mit der ersten Option kann die Regex-Engine alle Übereinstimmungen finden, dann werden sie in einer Aktion ersetzt und die Geschwindigkeit von Ruby 1.9.3 wird um das Zweifache verbessert.gsub(/\A\[/, "")
?Ineffiziente Alternative:
quelle
Zum Beispiel: a = "Eins Zwei Drei"
Auf diese Weise können Sie nacheinander das erste Zeichen der Zeichenfolge entfernen.
quelle
Einfacher Weg:
Genialer Weg:
(Hinweis: lieber einfach :))
quelle
"[12,23,987,43".reverse.chop.reverse
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 sind nicht sehr semantisch / klar darüber, was passiert ([1..-1]
: "Ähm, ein Bereich von 1 bis negativ 1? Yearg?"), Oder sie sind langsam oder langwierig schreibe aus (.gsub
,.length
).Was wir versuchen, ist eine 'Verschiebung' (im Array-Sprachgebrauch), die jedoch die verbleibenden Zeichen zurückgibt, anstatt das, was verschoben wurde. Verwenden wir unseren Ruby, um dies mit Strings zu ermöglichen! Wir können die schnelle Klammeroperation verwenden, aber geben Sie ihr einen guten Namen und nehmen Sie ein Argument, um anzugeben, wie viel wir von vorne abkauen möchten:
Mit dieser schnellen, aber unhandlichen Klammeroperation können wir jedoch noch mehr tun. Wenn wir gerade dabei sind, schreiben wir der Vollständigkeit halber ein
#shift
und#first
für String (warum sollte Array den ganzen Spaß haben) und nehmen ein Argument, um anzugeben, wie viele Zeichen wir von Anfang an entfernen möchten:Ok, jetzt haben wir eine gute Möglichkeit, Zeichen von der Vorderseite eines Strings zu ziehen, mit einer Methode, die mit
Array#first
und übereinstimmtArray#shift
(was eigentlich eine Knallmethode sein sollte?). Und wir können den modifizierten String auch leicht mit bekommen#eat!
. Hm, sollten wir unsere neueeat!
Kraft mit Array teilen ? Warum nicht!Jetzt können wir:
Das ist besser!
quelle
chip()
anstelle vonchop()
(undchimp()
als Analogon vonchomp()
).quelle
quelle
Regex verwenden:
quelle
Ich finde eine gute Lösung
str.delete(str[0])
für die Lesbarkeit, obwohl ich die Leistung nicht bestätigen kann.quelle
List löscht ein oder mehrere Elemente vom Anfang des Arrays, mutiert das Array nicht und gibt das Array selbst anstelle des abgelegten Elements zurück.
quelle