Navegação nas séries



  • O primeiro elemento de uma série é chamado  "head". Como veremos, ele pode não ser o "first" (primeiro) dependendo de como manipulamos a série;
  • DEPOIS último elemento da série tem uma coisa chamada "tail" (cauda). Ele não tem um valor.
  • Toda a série tem um "entry index". A melhor definição disto é "onde a parte utilizável da série começa. Muitas operações com séries tem esse "entry index" como ponto de partida. Você pode mover o entry index para frente e para trás para mudar o resultado de suas operações.
  • Todo elemento da séria tem um número "índex" começando com 1 (não zero!) na primeira posição.
  • Começando na posição do entry index, os elementos da série tem apelidos: "first" para o primeiro, "second" para o segundo "third"para o terceiro, "fourth" para o quarto e  "fifth" para o quinto.

Nota: eu inventei o nome "entry index". Não está na documentação. Eu já ví o "entry index" sendo chamando apenas de "index", mas eu não gosto disso, pois pode causer confusão com o número index dos elementos da série.

action! head? action! tail? action! index?

Essas palavras pre-definidas retornam informações sobre a posição do entry index. Se o entry index está na head, head? returna true, senão false. A mesma lógica se aplica para tail?index? retorna o número index da posição do entry index.

Os exemplos a seguir devem deixar o seu uso claro:.

Primeiro criamos a série com os strings "cat" "dog" "fox" "cow" "fly" "ant" "bee" :

>> s: [ "cat" "dog" "fox" "cow" "fly" "ant" "bee" ]
== ["cat" "dog" "fox" "cow" "fly" "ant" "bee"]

Teremos algo assim:

>> head? s
== true

>> index? s
== 1

>> print first s
cat

action! head  action! tail

head move o entry index para o primeiro elemento da série, o "head".

tail move o entry index para a posição APÓS o último elemento da série, o "tail".

head e tail por si só não alteram a série, head apenas retorna toda a série, e  tail não retorna nada. Para alterar uma série é preciso fazer uma atribuição de valor, por exemplo: list: head list

action! next

next move o entry index um elemento em direção ao tail. Note que  next apenas retorna a série, não a modifica. Assim, simplesmente repetir next na mesma série não vai fazer o entry index ir além da segunda posição, pois você estará aplicando o comando na série original, onde o entry index ainda esta no primeiro elemento. Assim, para a maior parte dos usos, é preciso fazer uma atribuição, por exemplo: s: next s.

>> s: next s
== ["dog" "fox" "cow" "fly" "ant" "bee"]

Agora temos:

>> print s
dog fox cow fly ant bee

>> head? s
== false

>> print first s
dog

>> index? s
== 2

Note que, apesar do primeiro elemento agora ser "dog", seu índice ainda continua sendo 2!

action! back

back é o oposto de next: move o entry index um elemento em direção ao "head". Se você usar back na nossa série s, "cat" é trazido de volta! Ele nunca foi "apagado"!

Isto significa que o Red nunca descartou nada da antiga série s. Essa é uma das peculiaridades do Red, os dados estão sempre lá, no próprio código.

Depois de mover o índice da nossa série s, mesmo que você atribua esta série a outra palavra (variável), como b(b: s) você ainda pode executar movimentações e recuperar valores "escondidos na série b, pois b e s apontam para os mesmos dados.

Se você quer evitar isso , você deve criar a sua nova variável usando copy

Como já foi mencionado antes, em Red, diferentemente das outras linguagens, a variável (palavra) é associada aos dados, e não o contrário.

action! skip

Move o entry index um determinado número de elementos em direção ao tail.

>> s: skip s 3
== ["fly" "ant" "bee"]

>> print s
fly ant bee

>> print first s
fly

>> print index? s
5

Se o número de skips for maior que o número de elementos da série, o entry index permanece na tail.

>> s: skip s 100
== []

>> tail? s
== true

>> index? s
== 8

Você também pode executar um número negativo de skips, o que faz o entry index ir em direção ao head:

>> s: skip s -4
== ["cow" "fly" "ant" "bee"]

>> print first s
cow

>> print index? s
4