Séries matemáticas, considere, por exemplo, a sequência consecutiva representada aqui como uma matriz:
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) };
Impressões:
a0 = 0
a1 = 1
a2 = 2
...
a8 = 8
a9 = 9
Minhas perguntas: 1- Existe uma maneira simples de eliminar apenas o primeiro elemento, ou seja, a0 = 0
da saída impressa?
2- Esse código pode ser mais idiomático?
Obrigado.
Respostas:
Uma solução barebones
Vamos começar com uma solução muito simples para imprimir uma essência de uma sequência. Ele não trata das especificidades que você adicionou à sua pergunta, mas é um bom ponto de partida:
Ao contrário
.kv
, o que converte seu invocante no formuláriokey1, value1, key2, value2, key3, value3, ...
, ou seja, 6 elementos se o invocante contiver 3 elementos,.pairs
converte o invocante no formuláriokey1 => value1, key2 => value2, key3 => value3, ...
.Eu usei em
.pairs
vez de em.kv
parte porque isso significava que eu poderia usar».gist
mais tarde no código para obter umakey1 => value1
exibição agradável para cada elemento sem esforço . Vamos modificar isso abaixo, mas este é um bom começo idiomático.As chamadas
.head
e.tail
são a maneira idiomática de criar pequenas listas do primeiro e do último N elementos a partir de uma lista invocante (desde que não seja preguiçoso; mais sobre isso em breve).Dada esta solução inicial,
say seq-range-gist (0,1 ... Inf)[^10]
exibe:Em seguida, queremos poder "soltar apenas o primeiro elemento ... da saída impressa". Infelizmente
say seq-range-gist (0,1 ... Inf)[1..9]
exibe:Queremos que o número à esquerda do
=>
retenha a numeração da sequência original. Para habilitar isso, dividimos a sequência subjacente do intervalo que queremos extrair. Nós adicionamos um segundo parâmetro / argumento@range
e anexamos[@range]
à segunda linha do sub:Agora podemos escrever
say seq-range-gist (0,1 ... Inf), 1..9
para exibir:Na sua pergunta, você usou o formato em
aINDEX = VALUE
vez deINDEX => VALUE
. Para permitir a personalização da essência, adicionamos um terceiro&gist
parâmetro / argumento de rotina e chamamos isso em vez do.gist
método incorporado :Observe como as invocações de "método" no corpo de
seq-range-gist
sub são agora.&gist
, não.gist
. A sintaxe.&foo
chama um sub&foo
(que normalmente é chamado apenas por escritofoo
), passando o invocante à esquerda do.
como$_
argumento para o sub.Observe também que eu fiz o
&gist
parâmetro nomeado, precedendo-o com a:
.Então agora é
say seq-range-gist (0,1 ... Inf), 1..9, gist => { "a{.key} = {.value}" }
exibido:Adicionando polonês
O restante desta resposta é um material bônus para os leitores que se preocupam com o polimento.
say seq-range-gist (0, 1, 2, 3), ^3
exibe:Opa E mesmo que houvesse mais pares do que a cabeça e a cauda combinadas, pelo menos não tivéssemos linhas repetidas, ainda não faria sentido usar a
head, ..., tail
abordagem para eliminar apenas um ou dois elementos. Vamos alterar a última declaração no sub-corpo para eliminar esses problemas:Em seguida, seria bom se o sub fizesse algo útil se chamado sem um intervalo ou essência. Podemos principalmente corrigir isso, fornecendo os parâmetros
@range
e&gist
padrões adequados:Se não
@seq
for preguiçoso , o padrão será o intervalo completo de . Se for infinito (nesse caso, também é preguiçoso), o padrão de até 100 está bom. Mas e se for preguiçoso, mas produzir menos de 100 valores definidos? Para cobrir este caso, anexamos à declaração:@range
@seq
@seq
@seq
.grep: *.value.defined
@pairs
Outra melhoria simples seria parâmetros opcionais de cabeça e cauda, levando a uma solução final polida:
fonte
...
parte, fazendo com que parecesse mais um programa em C. Então, isso responde às duas partes da minha pergunta, realmente. Quanto à solução 'abrangente', parece um pouco intimidadora, na verdade.Você pode pular os primeiros N valores em qualquer um
Iterable
ouSequence
comskip
:Se você não especificar um número, ele ignorará apenas um elemento.
fonte
skip
parece remover apenas o ouput ou seja, o elemento com o índice de 0 (A0) restos. Eu tentei@seq:delete
e ele simplesmente substituiu o elemento 0 com(Any)
skip
irá apenas agir como se os elementos ignorados não existissem. Isto pode ou não pode ser o que quiser :-)skip
no meio para que ele lê:for @seq[^10].skip(0).kv
ele literalmente não ignorar o elemento 0 e não importa se eu dou como o argumento paraskip
1 ou 2, ele só distorce a fora ainda. Eu preciso de uma maneira prática de remover o 0º elemento do zero.for @seq[^10].kv.skip(2)
seja o que você está procurando?skip
depois do,.kv
mas usando argumentos diferentes de 2, para que não funcionasse. Obrigado pela solução.Isso pode ser um pouco mais idiomático:
Você não precisa usar uma variável lexical dentro da sequência; quer
Whatever
ou variáveis de marcador de posição pode ser utilizada com segurança dentro de sequências. Depois, você pode simplesmente selecionar os elementos da sequência que deseja imprimir. Que retorna«(0 1 2 3)(7 8 9 10)»
fonte
whatever
operador está atualizando, mas a saída de série / sequência não soluciona o problema principal. Eu gostaria de imprimir as séries como elas são vistas nos manuais de matemática, ou seja, com a...
notação intermediária.