Respuestas:
La variante de Shnipersons responde:
my $a='0123456789';
with $a {$_=.comb[(^* ∖ (1..3, 8).flat).keys.sort].join};
say $a;
En una linea:
say '0123456789'.comb[(^* ∖ (1..3, 8).flat).keys.sort].join;
o llamado por una función:
sub remove($str, $a) {
$str.comb[(^* ∖ $a.flat).keys.sort].join;
}
say '0123456789'.&remove: (1..3, 8);
o con 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
si solo lo hace un método de flotación libre y lo llama como 'foobar'.&remove: (1..2, 4);
(el aumento puede tener problemas con la composición si se usa varias veces)
.&remove
es una forma de eliminarlo.
Mi última idea para una operación de no-at (cubriré la implementación a continuación):
Uso:
say '0123456789'[- 1..3, 8 ]; # 045679
Implementación, envoltura (una variante de) la solución 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 sintaxis para usar el operador que he declarado es string[- list-of-indices-to-be-subtracted ]
, es decir, usar una [...]
notación familiar , pero con una cadena a la izquierda y un signo menos después de la apertura [
para indicar que el contenido del subíndice es una lista de exdices en lugar de índices. .
[Editar: he reemplazado mi implementación original con la de Brad. Probablemente sea erróneo porque, como señala Brad, su solución "asume que los [exdices] están en orden de más bajo a más alto, y no hay superposición", y aunque el suyo no promete lo contrario, el uso [- ... ]
es muy cercano a haciéndolo. Entonces, si alguien usara esta sintaxis, probablemente no debería usar la solución de Brad. Quizás haya una manera de eliminar la suposición de Brad.]
Me gusta esta sintaxis, pero sé que Larry lo hizo deliberadamente no creó el uso [...]
para indexar cadenas, por lo que tal vez mi sintaxis aquí sea inapropiada para una adopción generalizada. Quizás sería mejor si se usaran algunos caracteres de horquillado diferentes. Pero creo que el uso de una sintaxis simple postcircumfix es bueno.
(También he intentado implementar una [ ... ]
variante directa para indexar cadenas exactamente de la misma manera que para Positional
s, pero no he logrado que funcione por razones ajenas a mí esta noche.[+ ... ]
trabajaré para hacer exdices pero no para hacer índices; eso hace que ¡No tiene ningún sentido para mí! De todos modos, publicaré lo que tengo y consideraré esta respuesta completa.)
[Editar: La solución anterior tiene dos aspectos que deberían verse como distintos. Primero, un operador definido por el usuario, el azúcar sintáctico proporcionado por elpostcircumfix:<[- ]> (Str ...
declaración. En segundo lugar, el cuerpo de esa declaración. En lo anterior, he usado (una variante de) la solución de Brad. Mi respuesta original está abajo.]
Debido a que su pregunta se reduce a eliminar algunos índices de a [Editar: Incorrecto, según la respuesta de Brad.].comb
, y obtener join
el resultado, su pregunta es esencialmente un duplicado de ...
¿Cuál es una forma rápida de deseleccionar la matriz o elementos de la lista?agrega aún más soluciones para el [.comb ... .join
respuestas ] aquí.
Implementado como dos multis para que la misma sintaxis se pueda usar 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)
La sort keys ^@pos (-) @exdices
implementación es solo una versión ligeramente simplificada de la respuesta de @ Sebastian. No lo he comparado con la solución de jnthn de la respuesta anterior que vinculé anteriormente, pero si eso es más rápido, entonces se puede intercambiar. * [Editar: Obviamente, debería ser la solución de Brad para la variante de cadena.] *
otras variantes más:
print $_[1] if $_[0] !(elem) (1,2,3,8) for ^Inf Z 0..9;
.print for ((0..9) (-) (1,2,3,8)).keys;
Todos están convirtiendo la cadena en una lista usando comb
o usando una lista plana de índices.
No hay razón para hacer ninguna de esas cosas.
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
Lo anterior supone que los índices están en orden de menor a mayor, y no hay superposición.
my $s = "0123456789" x 1000; my $l = (1..3, 8, 40, 100, 1001, 4000..4100).flat
). El peine es largo para largas cadenas Gracias @BradGilbert, esto definitivamente ayudará a algunas personas, al menos a mí :-)
.comb
tiene que crear muchos de esos objetos y combinarlos nuevamente. Con substr
esto crea la menor cantidad posible de esos objetos.