Risposte:
La variante di Shnipersons risponde:
my $a='0123456789';
with $a {$_=.comb[(^* ∖ (1..3, 8).flat).keys.sort].join};
say $a;
In una riga:
say '0123456789'.comb[(^* ∖ (1..3, 8).flat).keys.sort].join;
o chiamato da una funzione:
sub remove($str, $a) {
$str.comb[(^* ∖ $a.flat).keys.sort].join;
}
say '0123456789'.&remove: (1..3, 8);
o con aumento di Str:
use MONKEY-TYPING;
augment class Str {
method remove($a) {
$.comb[(^* ∖ $a.flat).keys.sort].join;
}
};
say '0123456789'.remove: (1..3, 8);
MONKET-TYPING
se lo rendi solo un metodo mobile libero e lo chiami come 'foobar'.&remove: (1..2, 4);
(aumentando può avere problemi con la composizione se usato più volte)
.&remove
è un modo per rimuoverlo.
La mia ultima idea per un'operazione non attiva (tratterò l'implementazione di seguito):
Uso:
say '0123456789'[- 1..3, 8 ]; # 045679
Implementazione, wrapping (una variante della) Soluzione di Brad:
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
La sintassi per usare l'operatore che ho dichiarato è string[- list-of-indices-to-be-subtracted ]
, cioè usando una [...]
notazione familiare , ma con una stringa a sinistra e un segno meno dopo l'apertura [
per indicare che il contenuto del pedice è un elenco di exdices piuttosto che di indici .
[Modifica: ho sostituito la mia implementazione originale con quella di Brad. Probabilmente è sbagliato perché, come osserva Brad, la sua soluzione "presume che gli [exdices] siano in ordine dal più basso al più alto, e non vi siano sovrapposizioni", e mentre il suo non promette diversamente, usare [- ... ]
è terribilmente vicino a così facendo. Quindi, se questo zucchero di sintassi dovesse essere usato da qualcuno, probabilmente non dovrebbe usare la soluzione di Brad. Forse c'è un modo per eliminare il presupposto di Brad.]
Mi piace questa sintassi ma sono consapevole del fatto che Larry non è stato deliberatamente utilizzato [...]
per indicizzare le stringhe, quindi forse la mia sintassi qui non è appropriata per l'adozione diffusa. Forse sarebbe meglio se fossero usati alcuni caratteri di bracketing diversi. Ma penso che l'uso di una semplice sintassi postcircumfix sia piacevole.
(Ho anche provato a implementare una [ ... ]
variante semplice per indicizzare le stringhe esattamente allo stesso modo di Positional
s ma non sono riuscito a farlo funzionare per motivi al di là di me stanotte. Stranamente [+ ... ]
lavoreremo per fare degli exd ma non per fare gli indici; questo rende non ha alcun senso per me! Ad ogni modo, posterò quello che ho e considero completa questa risposta.)
[Modifica: la soluzione sopra ha due aspetti che dovrebbero essere visti come distinti. Innanzitutto, un operatore definito dall'utente, lo zucchero sintattico fornito dalla postcircumfix:<[- ]> (Str ...
dichiarazione. In secondo luogo, il corpo di tale dichiarazione. In quanto sopra ho usato (una variante della) soluzione di Brad. La mia risposta originale è sotto.]
Poiché la tua domanda si riduce alla rimozione di alcuni indici di a [Modifica: Sbagliato, secondo la risposta di Brad.].comb
, e alla rielaborazione join
del risultato, la tua domanda è essenzialmente un duplicato di ...
Qual è un modo rapido per deselezionare gli elementi dell'array o dell'elenco? aggiunge ancora più soluzioni per le [ .comb ... .join
] risposte qui.
Implementato come due multis in modo che la stessa sintassi possa essere utilizzata con 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)
L' sort keys ^@pos (-) @exdices
implementazione è solo una versione leggermente semplificata della risposta di @ Sebastian. Non l'ho confrontato con la soluzione di jnthn dalla risposta precedente che ho collegato sopra, ma se è più veloce allora può essere scambiato. * [Modifica: ovviamente dovrebbe essere invece la soluzione di Brad per la variante di stringa.] *
ancora altre varianti:
print $_[1] if $_[0] !(elem) (1,2,3,8) for ^Inf Z 0..9;
.print for ((0..9) (-) (1,2,3,8)).keys;
Ognuno sta trasformando la stringa in un elenco usando comb
o usando un elenco piatto di indici.
Non c'è motivo di fare nessuna di queste cose
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
Quanto sopra presuppone che gli indici siano in ordine dal più basso al più alto e che non vi siano sovrapposizioni.
my $s = "0123456789" x 1000; my $l = (1..3, 8, 40, 100, 1001, 4000..4100).flat
). Il pettine è lungo per le corde lunghe Grazie @BradGilbert, questo aiuterà sicuramente alcune persone, almeno io :-)
.comb
deve creare molti di quegli oggetti e combinarli di nuovo insieme. Con substr
esso crea il minor numero possibile di quegli oggetti.