Réponses:
Variante de Shnipersons réponse:
my $a='0123456789';
with $a {$_=.comb[(^* ∖ (1..3, 8).flat).keys.sort].join};
say $a;
En une seule ligne:
say '0123456789'.comb[(^* ∖ (1..3, 8).flat).keys.sort].join;
ou appelé par une fonction:
sub remove($str, $a) {
$str.comb[(^* ∖ $a.flat).keys.sort].join;
}
say '0123456789'.&remove: (1..3, 8);
ou avec augmentation de Str:
use MONKEY-TYPING;
augment class Str {
method remove($a) {
$.comb[(^* ∖ $a.flat).keys.sort].join;
}
};
say '0123456789'.remove: (1..3, 8);
MONKET-TYPING
si vous le rendez juste une méthode flottante gratuite et l'appelez comme 'foobar'.&remove: (1..2, 4);
(l'augmentation peut avoir des problèmes de composition si elle est utilisée plusieurs fois)
.&remove
c'est un moyen de supprimer cela.
Ma dernière idée pour une opération non-at (je couvrirai la mise en œuvre ci-dessous):
Usage:
say '0123456789'[- 1..3, 8 ]; # 045679
Implémentation, emballage (une variante de) la solution de 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 syntaxe pour utiliser l'opérateur que j'ai déclaré est string[- list-of-indices-to-be-subtracted ]
, c'est-à-dire en utilisant une [...]
notation familière , mais avec une chaîne à gauche et un moins supplémentaire après l'ouverture [
pour indiquer que le contenu de l'indice est une liste d' exdices plutôt que des indices .
[Modifier: j'ai remplacé mon implémentation d'origine par celle de Brad. C'est probablement faux parce que, comme le note Brad, sa solution "suppose que les [exdices] sont dans l'ordre du plus bas au plus élevé, et il n'y a pas de chevauchement.", Et bien que son ne promette pas le contraire, l'utilisation [- ... ]
est terriblement proche de Ce faisant. Donc, si ce sucre de syntaxe devait être utilisé par quelqu'un, il ne devrait probablement pas utiliser la solution de Brad. Il y a peut-être un moyen d'éliminer l'hypothèse de Brad.]
J'aime cette syntaxe, mais je suis conscient que Larry n'a pas délibérément construit en utilisant [...]
pour indexer des chaînes, alors peut-être que ma syntaxe ici n'est pas appropriée pour une adoption généralisée. Il serait peut-être préférable d'utiliser des caractères de bracketing différents. Mais je pense que l'utilisation d'une simple syntaxe postcircumfix est agréable.
(J'ai également essayé d'implémenter une [ ... ]
variante directe pour l'indexation de chaînes exactement de la même manière que pour Positional
s mais je n'ai pas réussi à le faire fonctionner pour des raisons qui me dépassent ce soir. Bizarrement, [+ ... ]
cela fonctionnera pour faire des exdices mais pas des index; cela fait aucun sens pour moi! Quoi qu'il en soit, je vais publier ce que j'ai et considérer cette réponse comme complète.)
[Edit: La solution ci-dessus a deux aspects qui doivent être considérés comme distincts. Tout d'abord, un opérateur défini par l'utilisateur, le sucre syntaxique fourni par la postcircumfix:<[- ]> (Str ...
déclaration,. Deuxièmement, le corps de cette déclaration. Dans ce qui précède, j'ai utilisé (une variante de) la solution de Brad. Ma réponse originale est ci-dessous.]
Parce que votre question se résume à la suppression de certains indices de a [Edit: Wrong, per Brad's answer.].comb
et join
au résultat, votre question est essentiellement un double de ...
Quel est un moyen rapide de désélectionner des éléments de tableau ou de liste? ajoute encore plus de solutions pour les .comb ... .join
réponses [ ] ici.
Implémenté en deux multis afin que la même syntaxe puisse être utilisée avec 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
implémentation n'est qu'une version légèrement simplifiée de la réponse de @ Sebastian. Je ne l'ai pas comparé à la solution de jnthn de la réponse précédente que j'ai liée ci-dessus, mais si c'est plus rapide, il peut être échangé à la place. * [Edit: Evidemment, ce devrait plutôt être la solution de Brad pour la variante de chaîne.] *
encore une autre variante:
print $_[1] if $_[0] !(elem) (1,2,3,8) for ^Inf Z 0..9;
.print for ((0..9) (-) (1,2,3,8)).keys;
Tout le monde transforme la chaîne en liste en utilisant comb
ou en utilisant une liste plate d'index.
Il n'y a aucune raison de faire l'une ou l'autre de ces choses
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
Ce qui précède suppose que les indices sont dans l'ordre du plus bas au plus élevé, et qu'il n'y a pas de chevauchement.
my $s = "0123456789" x 1000; my $l = (1..3, 8, 40, 100, 1001, 4000..4100).flat
). Le peigne est long pour de longues cordes Merci @BradGilbert, cela aidera certainement certaines personnes, au moins moi :-)
.comb
créer un grand nombre de ces objets et les regrouper. Avec substr
cela, il crée le moins possible de ces objets.