Respostas:
Variante da resposta de Shniperson:
my $a='0123456789';
with $a {$_=.comb[(^* ∖ (1..3, 8).flat).keys.sort].join};
say $a;
Em uma linha:
say '0123456789'.comb[(^* ∖ (1..3, 8).flat).keys.sort].join;
ou chamado por uma função:
sub remove($str, $a) {
$str.comb[(^* ∖ $a.flat).keys.sort].join;
}
say '0123456789'.&remove: (1..3, 8);
ou com aumento 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
método flutuante gratuito e chamá-lo como 'foobar'.&remove: (1..2, 4);
(o aumento pode ter problemas com a composição, se usado várias vezes)
.&remove
é uma maneira de removê-lo.)
Minha última idéia para uma operação que não está no momento (abordarei a implementação abaixo):
Uso:
say '0123456789'[- 1..3, 8 ]; # 045679
Implementação, encapsulamento (uma variante) da solução 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
A sintaxe para usar o operador que declarei é string[- list-of-indices-to-be-subtracted ]
, ou seja, usando [...]
notação familiar , mas com uma sequência à esquerda e um sinal[
de menos adicional após a abertura para indicar que o conteúdo subscrito é uma lista de exdices em vez de índices .
[Editar: Substituí minha implementação original pela de Brad. Provavelmente isso está errado, porque, como observa Brad, sua solução "assume que os [exdices] estão na ordem do mais baixo para o mais alto, e não há sobreposição", e, embora ele não prometa o contrário, o uso [- ... ]
é muito próximo de fazendo isso. Portanto, se esse açúcar de sintaxe fosse usado por alguém, ele provavelmente não deveria usar a solução de Brad. Talvez haja uma maneira de eliminar a suposição de Brad.]
Eu gosto desta sintaxe, mas estou ciente de que Larry deliberadamente se não construir no uso de [...]
para cadeias índice então talvez o meu sintaxe aqui é inapropriado para adopção generalizada. Talvez seja melhor se alguns caracteres de bracketing diferentes forem usados. Mas acho que o uso de uma simples sintaxe postcircumfix é bom.
(Eu também tentei implementar uma [ ... ]
variante direta para indexar strings da mesma maneira que para Positional
s, mas não consegui fazê-lo funcionar por razões além de mim hoje à noite. Estranhamente [+ ... ]
, trabalhará para executar exdices, mas não para índices; isso faz com que não faz sentido para mim! De qualquer forma, vou postar o que tenho e considerar esta resposta completa.)
[Editar: A solução acima tem dois aspectos que devem ser vistos como distintos. Primeiro, um operador definido pelo usuário, o açúcar sintático fornecido pela postcircumfix:<[- ]> (Str ...
declaração Segundo, o corpo dessa declaração. No exemplo acima, usei (uma variante da) solução de Brad. Minha resposta original está abaixo.]
Como sua pergunta se resume a remover alguns índices de a [Editar: Errado, de acordo com a resposta de Brad.].comb
e obter join
o resultado, sua pergunta é essencialmente uma duplicata de ...
Qual é uma maneira rápida de desmarcar matriz ou listar elementos? adiciona ainda mais soluções para as [ .comb ... .join
] respostas aqui.
Implementado como dois multis, para que a mesma sintaxe possa ser usada com 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)
A sort keys ^@pos (-) @exdices
implementação é apenas uma versão ligeiramente simplificada da resposta de @ Sebastian. Eu não o comparei com a solução do jnthn da resposta anterior que eu vinculei acima, mas se for mais rápido, pode ser trocado. * [Edit: Obviamente, deveria ser a solução de Brad para a variante de string.] *
ainda outras variantes:
print $_[1] if $_[0] !(elem) (1,2,3,8) for ^Inf Z 0..9;
.print for ((0..9) (-) (1,2,3,8)).keys;
Todo mundo está transformando a string em uma lista usando comb
ou usando uma lista simples de índices.
Não há razão para fazer uma dessas coisas
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
O exposto acima pressupõe que os índices estão na ordem do menor para o maior e não há sobreposição.
my $s = "0123456789" x 1000; my $l = (1..3, 8, 40, 100, 1001, 4000..4100).flat
). Pente é longo para longas cordas Obrigado @BradGilbert, isso definitivamente ajudará algumas pessoas, pelo menos eu :-)
.comb
ele deve criar muitos desses objetos e combiná-los novamente. Com substr
isso, cria o menor número possível de objetos.