Série mathématique, prenez par exemple la séquence consécutive représentée ici sous forme de tableau:
my @seq = my $a=0, {++$a} ... *;
for @seq[^10].kv {state $f=0; ($^k < 4 or $^k > 7) ?? say "a$^k = " ~ $^v !! (say "..." if $f ne 1; $f=1) };
Tirages:
a0 = 0
a1 = 1
a2 = 2
...
a8 = 8
a9 = 9
Mes questions: 1- Existe-t-il un moyen simple de supprimer uniquement le premier élément, c'est- a0 = 0
à- dire de la sortie imprimée?
2- Ce code pourrait-il être rendu plus idiomatique?
Je vous remercie.
Réponses:
Une solution barebones
Commençons par une solution très simple pour imprimer l'essentiel d'une séquence. Il ne traite pas des détails que vous avez ajoutés à votre question, mais c'est un bon point de départ:
Contrairement
.kv
, qui convertit son invocant en formekey1, value1, key2, value2, key3, value3, ...
, c'est-à-dire 6 éléments si son invocant contient 3 éléments,.pairs
convertit son invocant en formekey1 => value1, key2 => value2, key3 => value3, ...
.J'ai utilisé
.pairs
au lieu de.kv
partiellement parce que cela signifiait que je pouvais simplement utiliser».gist
plus tard dans le code pour obtenir sans effort un belkey1 => value1
affichage pour chaque élément. Nous allons modifier cela ci-dessous mais c'est un bon début idiomatique.Le
.head
et.tail
appels sont le moyen idiomatique de créer de petites listes des premier et dernier N éléments à partir d'une liste invocante (à condition que ce ne soit pas paresseux; plus à ce sujet dans un mois).Compte tenu de cette solution initiale,
say seq-range-gist (0,1 ... Inf)[^10]
affiche:Ensuite, nous voulons pouvoir "supprimer uniquement le premier élément ... de la sortie imprimée".
say seq-range-gist (0,1 ... Inf)[1..9]
Affiche malheureusement :Nous voulons que le numéro à gauche de la
=>
conserve la numérotation de la séquence d'origine. Pour activer cela, nous séparons la séquence sous-jacente de la plage que nous voulons extraire. Nous ajoutons un deuxième paramètre / argument@range
, et ajoutons[@range]
à la deuxième ligne du sous:Maintenant, nous pouvons écrire
say seq-range-gist (0,1 ... Inf), 1..9
pour afficher:Dans votre question, vous avez utilisé le format
aINDEX = VALUE
plutôt queINDEX => VALUE
. Pour permettre la personnalisation de l'essentiel, nous ajoutons un troisième&gist
paramètre / argument de routine et l'invoquons à la place de la.gist
méthode intégrée :Notez comment les invocations de "méthode" dans le corps de
seq-range-gist
sub ne sont.&gist
plus.gist
. La syntaxe.&foo
invoque un sous - marin&foo
(qui est généralement appelé en écrivant simplementfoo
), en passant l'invocant à gauche de l' argument.
comme$_
argument au sous-marin.Notez également que j'ai rendu le
&gist
paramètre nommé en le précédant d'un:
.say seq-range-gist (0,1 ... Inf), 1..9, gist => { "a{.key} = {.value}" }
Affiche maintenant :Ajout de vernis
Le reste de cette réponse est du matériel bonus pour les lecteurs qui se soucient du polonais.
say seq-range-gist (0, 1, 2, 3), ^3
affiche:Oops. Et même s'il y avait plus de paires que la tête et la queue combinées, donc au moins nous n'avions pas de lignes répétées, il serait toujours inutile d'utiliser l'
head, ..., tail
approche pour élider un ou deux éléments. Modifions la dernière instruction du sous-corps pour éliminer ces problèmes:Ensuite, ce serait bien si le sous-marin faisait quelque chose d'utile s'il était appelé sans plage ni contenu. Nous pouvons principalement résoudre ce problème en donnant aux paramètres
@range
et&gist
les valeurs par défaut appropriées:Si
@seq
n'est pas paresseux , par@range
défaut, la plage complète de@seq
. Si@seq
est infini (auquel cas il est également paresseux), la valeur par défaut jusqu'à 100 est correcte. Mais que faire si@seq
est paresseux mais donne moins de 100 valeurs définies? Pour couvrir ce cas, nous annexons.grep: *.value.defined
à la@pairs
déclaration:Une autre amélioration simple serait les paramètres facultatifs de tête et de queue, conduisant à une solution finale polie:
la source
...
partie qui la faisait ressembler davantage à un programme C. Donc, cela répond vraiment aux deux parties de ma question. Quant à la solution «globale», elle semble vraiment un peu intimidante.Vous pouvez ignorer les N premières valeurs sur n'importe laquelle
Iterable
ouSequence
avecskip
:Si vous ne spécifiez pas de nombre, il ne sautera qu'un seul élément.
la source
skip
semble supprimer uniquement la sortie, c'est-à-dire que l'élément avec le 0ème indice (a0) reste. J'ai essayé@seq:delete
et il vient de remplacer le 0ème élément par(Any)
skip
va simplement agir comme si les éléments ignorés n'existaient pas. Cela peut ou non être ce que vous voulez :-)skip
entre entre deux pour qu'il se lise:for @seq[^10].skip(0).kv
il ne saute littéralement pas le 0ème élément et peu importe si je donne comme argument àskip
1 ou 2, cela déforme juste la sortie de plus. J'ai besoin d'un moyen pratique pour retirer le 0ème élément du sol.for @seq[^10].kv.skip(2)
- être ce que vous cherchez?skip
after,.kv
mais en utilisant des arguments autres que 2, donc cela n'a pas fonctionné. Merci pour la solution.Cela pourrait être un peu plus idiomatique:
Vous n'avez pas besoin d'utiliser une variable lexicale dans la séquence; l'une
Whatever
ou l' autre des variables d'espace réservé peuvent être utilisées en toute sécurité dans les séquences. Ensuite, vous pouvez simplement sélectionner les éléments de la séquence que vous souhaitez imprimer. Qui revient«(0 1 2 3)(7 8 9 10)»
la source
whatever
opérateur rafraîchit mais la sortie série / séquence ne résout pas le problème principal. Je voudrais imprimer la série telle qu'elle apparaît sur les livres de mathématiques, c'est-à-dire avec une...
notation entre les deux.