Odpowiedzi:
Odpowiedź na wariant Shnipersonów:
my $a='0123456789';
with $a {$_=.comb[(^* ∖ (1..3, 8).flat).keys.sort].join};
say $a;
W jednej linii:
say '0123456789'.comb[(^* ∖ (1..3, 8).flat).keys.sort].join;
lub wywoływane przez funkcję:
sub remove($str, $a) {
$str.comb[(^* ∖ $a.flat).keys.sort].join;
}
say '0123456789'.&remove: (1..3, 8);
lub z rozszerzeniem Str:
use MONKEY-TYPING;
augment class Str {
method remove($a) {
$.comb[(^* ∖ $a.flat).keys.sort].join;
}
};
say '0123456789'.remove: (1..3, 8);
MONKET-TYPING
jeśli po prostu uczynisz go metodą swobodną i wywołasz ją jako 'foobar'.&remove: (1..2, 4);
(augmentacja może mieć problemy z kompozycją, jeśli zostanie użyta kilka razy)
.&remove
jest to sposób na usunięcie tego.
Mój najnowszy pomysł na brak operacji (omówię implementację poniżej):
Stosowanie:
say '0123456789'[- 1..3, 8 ]; # 045679
Wdrożenie, opakowanie (wariant) rozwiązania Brada:
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
Składnia do użycia operatora, który zadeklarowałem, polega na string[- list-of-indices-to-be-subtracted ]
zastosowaniu znanej [...]
notacji, ale z ciągiem po lewej stronie i dodatkowym minusem po otwarciu, [
aby wskazać, że zawartość indeksu dolnego jest raczej listą ekscesów niż indeksów .
[Edytuj: Zastąpiłem moją oryginalną implementację wersją Brada. Prawdopodobnie jest to błędne, ponieważ, jak zauważa Brad, jego rozwiązanie „zakłada, że [ekscesy] są w porządku od najniższego do najwyższego, i nie ma nakładania się”, a chociaż nie obiecuje inaczej, używanie [- ... ]
jest okropnie bliskie robiąc tak. Więc jeśli ktoś miałby użyć tego cukru składniowego, prawdopodobnie nie powinien używać rozwiązania Brada. Być może istnieje sposób na wyeliminowanie założenia, które czyni Brad.]
Podoba mi się ta składnia, ale zdaję sobie sprawę, że Larry celowo nie budował w [...]
celu indeksowania ciągów, więc być może moja składnia jest nieodpowiednia do powszechnego przyjmowania. Być może byłoby lepiej, gdyby zastosowano kilka różnych znaków nawiasowych. Ale myślę, że użycie prostej składni postcircumfix jest fajne.
(Próbowałem również zaimplementować prosty [ ... ]
wariant do indeksowania ciągów w dokładnie taki sam sposób jak dla Positional
s, ale nie udało mi się sprawić, aby działał z innych przyczyn niż dziś wieczorem. Dziwnie [+ ... ]
będzie działał, aby robić exdices, ale nie indeksy; to sprawia, że nie ma dla mnie żadnego sensu! W każdym razie opublikuję to, co mam i uznam tę odpowiedź za kompletną).
[Edycja: Powyższe rozwiązanie ma dwa aspekty, które należy postrzegać jako odrębne. Po pierwsze, operator zdefiniowany przez użytkownika, cukier składniowy dostarczony przez postcircumfix:<[- ]> (Str ...
deklarację. Po drugie, treść tej deklaracji. Powyżej użyłem (wariant) rozwiązania Brada. Moja oryginalna odpowiedź znajduje się poniżej.]
Ponieważ twoje pytanie sprowadza się do usunięcia niektórych wskaźników [Edytuj: Źle, na odpowiedź Brada]..comb
i odnosząc join
się do wyniku, twoje pytanie jest zasadniczo duplikatem ...
Jaki jest szybki sposób na usunięcie zaznaczenia elementów tablicy lub listy? dodaje tutaj jeszcze więcej rozwiązań dla [ .comb ... .join
] odpowiedzi.
Zaimplementowane jako dwa multis, więc ta sama składnia może być używana z Positional
s:
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)
sort keys ^@pos (-) @exdices
Realizacja jest po prostu nieco uproszczona wersja @ odpowiedź Sebastiana. Nie porównałem go z rozwiązaniem Jnthna z wcześniejszej odpowiedzi, którą podałem powyżej, ale jeśli jest to szybsze, można go wymienić. * [Edycja: Oczywiście powinno to być rozwiązanie Brada dla wariantu łańcucha.] *
jeszcze inne warianty:
print $_[1] if $_[0] !(elem) (1,2,3,8) for ^Inf Z 0..9;
.print for ((0..9) (-) (1,2,3,8)).keys;
Wszyscy albo przekształcają ciąg znaków w listę, używając comb
płaskiej listy indeksów lub używając tej listy.
Nie ma powodu, aby robić jedną z tych rzeczy
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
Powyższe zakłada, że wskaźniki są uporządkowane od najniższego do najwyższego i nie ma nakładania się.
my $s = "0123456789" x 1000; my $l = (1..3, 8, 40, 100, 1001, 4000..4100).flat
). Grzebień jest długi na długie sznurki Dzięki @BradGilbert, to zdecydowanie pomoże niektórym ludziom, przynajmniej mnie :-)
.comb
go użyjesz, musisz utworzyć wiele z tych obiektów i połączyć je z powrotem. Dzięki substr
niemu powstaje jak najmniej takich obiektów.