Antworten:
Variante von Shnipersons Antwort:
my $a='0123456789';
with $a {$_=.comb[(^* ∖ (1..3, 8).flat).keys.sort].join};
say $a;
In einer Zeile:
say '0123456789'.comb[(^* ∖ (1..3, 8).flat).keys.sort].join;
oder von einer Funktion aufgerufen:
sub remove($str, $a) {
$str.comb[(^* ∖ $a.flat).keys.sort].join;
}
say '0123456789'.&remove: (1..3, 8);
oder mit Augmentation von Str:
use MONKEY-TYPING;
augment class Str {
method remove($a) {
$.comb[(^* ∖ $a.flat).keys.sort].join;
}
};
say '0123456789'.remove: (1..3, 8);
MONKET-TYPING
wenn Sie es einfach als frei schwebende Methode verwenden und es als 'foobar'.&remove: (1..2, 4);
(Augment kann Probleme mit der Komposition haben, wenn es mehrmals verwendet wird)
.&remove
ein Weg ist, dies zu entfernen.
Meine neueste Idee für eine Nicht-At-Operation (ich werde die Implementierung unten behandeln):
Verwendungszweck:
say '0123456789'[- 1..3, 8 ]; # 045679
Implementierung, Verpackung (eine Variante von) Brads Lösung:
multi postcircumfix:<[- ]> (|args) { remove |args }
sub remove( Str:D $str is copy, +@exdices){
for @exdices.reverse {
when Int { $str.substr-rw($_,1) = '' }
when Range { $str.substr-rw($_ ) = '' }
}
$str
}
say '0123456789'[- 1..3, 8 ]; # 045679
Die Syntax zur Verwendung des von mir deklarierten Operators lautet string[- list-of-indices-to-be-subtracted ]
, dh unter Verwendung der bekannten [...]
Notation, jedoch mit einer Zeichenfolge links und einem zusätzlichen Minus nach dem Öffnen, [
um anzuzeigen, dass der tiefgestellte Inhalt eine Liste von Exdices und keine Indizes ist .
[Bearbeiten: Ich habe meine ursprüngliche Implementierung durch die von Brad ersetzt. Das ist wahrscheinlich falsch, weil, wie Brad bemerkt, seine Lösung "davon ausgeht, dass die [Exdices] in der Reihenfolge vom niedrigsten zum höchsten sind und es keine Überlappung gibt.", Und obwohl er nichts anderes verspricht, ist die Verwendung [- ... ]
furchtbar nahe dabei. Wenn also dieser Syntaxzucker von jemandem verwendet werden soll, sollte er wahrscheinlich nicht Brads Lösung verwenden. Vielleicht gibt es einen Weg, die Annahme zu beseitigen, die Brad macht.]
Ich mag diese Syntax , aber bin mir bewusst , dass Larry bewusst habe nicht in Verwendung bauen [...]
so vielleicht zu indizieren Strings meine Syntax ist hier ungeeignet für weit verbreitete Annahme. Vielleicht wäre es besser, wenn verschiedene Klammerzeichen verwendet würden. Aber ich denke, die Verwendung einer einfachen Postcircumfix-Syntax ist nett.
(Ich habe auch versucht, eine gerade [ ... ]
Variante für die Indizierung von Zeichenfolgen genauso zu implementieren wie für Positional
s, aber ich habe es aus Gründen, die ich heute Abend [+ ... ]
nicht kenne, nicht zum Laufen gebracht . Seltsamerweise wird es funktionieren, Exdices zu machen, aber keine Indizes; das macht Für mich macht das überhaupt keinen Sinn! Wie auch immer, ich werde posten, was ich habe und diese Antwort als vollständig betrachten.)
[Bearbeiten: Die obige Lösung hat zwei Aspekte, die als unterschiedlich angesehen werden sollten. Zunächst ein benutzerdefinierter Operator, der syntaktische Zucker, der durch die postcircumfix:<[- ]> (Str ...
Deklaration bereitgestellt wird . Zweitens der Hauptteil dieser Erklärung. Oben habe ich (eine Variante von) Brads Lösung verwendet. Meine ursprüngliche Antwort ist unten.]
Da Ihre Frage darauf hinausläuft, einige Indizes von a zu entfernen [Bearbeiten: Falsch, gemäß Brads Antwort.].comb
und join
das Ergebnis zu überprüfen, ist Ihre Frage im Wesentlichen ein Duplikat von ...
Was ist eine schnelle Möglichkeit, Array- oder Listenelemente abzuwählen? fügt hier noch weitere Lösungen für die [ .comb ... .join
] Antworten hinzu.
Implementiert als zwei Multis, sodass dieselbe Syntax mit Positional
s verwendet werden kann:
multi postcircumfix:<[- ]> (Str $_, *@exdex) { .comb[- @exdex ].join }
multi postcircumfix:<[- ]> (@pos, *@exdex) { sort keys ^@pos (-) @exdex }
say '0123456789'[- 1..3, 8 ]; # 045679
say (0..9)[- 1..3, 8 ]; # (0 4 5 6 7 9)
Die sort keys ^@pos (-) @exdices
Implementierung ist nur eine leicht vereinfachte Version von @ Sebastians Antwort. Ich habe es nicht mit jnthns Lösung aus der früheren Antwort verglichen, die ich oben verlinkt habe, aber wenn das schneller ist, kann es stattdessen ausgetauscht werden. * [Bearbeiten: Natürlich sollte es stattdessen Brads Lösung für die String-Variante sein.] *
noch eine andere Variante:
print $_[1] if $_[0] !(elem) (1,2,3,8) for ^Inf Z 0..9;
.print for ((0..9) (-) (1,2,3,8)).keys;
Jeder verwandelt die Zeichenfolge entweder mithilfe comb
oder unter Verwendung einer flachen Liste von Indizes in eine Liste .
Es gibt keinen Grund, eines dieser Dinge zu tun
sub remove( Str:D $str is copy, +@indices ){
for @indices.reverse {
when Int { $str.substr-rw($_,1) = '' }
when Range { $str.substr-rw($_ ) = '' }
}
}
remove("0123456789", 1..3, 8 ); # 045679
remove("0123456789", [1..3, 8]); # 045679
Das Obige setzt voraus, dass die Indizes in der Reihenfolge vom niedrigsten zum höchsten sind und es keine Überlappung gibt.
my $s = "0123456789" x 1000; my $l = (1..3, 8, 40, 100, 1001, 4000..4100).flat
). Kamm ist lang für lange Saiten Danke @BradGilbert, das wird definitiv einigen Leuten helfen, zumindest mir :-)
.comb
Sie viele dieser Objekte erstellen und sie wieder miteinander kombinieren. Damit substr
entstehen möglichst wenige dieser Objekte.