In

Intervalos em Julia

1 exercício

Sobre Intervalos

Imagina que queres todos os números inteiros não negativos até 1000. Seria ridículo se tivesses de os escrever num array.

Para isso existe o tipo range:

julia> 0:1000
0:1000

julia> typeof(0:1000)
UnitRange{Int64}

Os ranges são muito comuns: não só para te poupar trabalho a escrever, mas também como tipos devolvidos por funções.

Repara que os ranges não são arrays.

Os arrays são definidos logo no início ("avaliação gulosa") e precisam de armazenamento proporcional ao comprimento do array.

Em contraste, os ranges são apenas um conjunto de instruções para gerar uma sequência (avaliação "preguiçosa", ou um "iterador").

Se precisares de um range como array, usa a função collect() para fazer a conversão:

julia> collect(0:5)
6-element Vector{Int64}:
 0
 1
 2
 3
 4
 5

Opcionalmente, usa collect(type, range) para especificar o tipo do array de saída.

Podes especificar o tamanho do passo, neste caso 0.3:

julia>  collect(1.0:0.3:2.0)
4-element Vector{Float64}:
 1.0
 1.3
 1.6
 1.9

Portanto, a sintaxe é start:stepsize:stop. Ambos os limites são inclusivos, como se vê no exemplo com números inteiros. Se o tamanho do passo não dividir exatamente stop - start, o último elemento evita ultrapassar stop.

Para um controlo mais fino, usa a função Base.range(), que tem várias opções adicionais.

Ranges de letras

Também se podem usar sequências não numéricas em ranges. O exemplo mais simples são as letras ASCII:

julia> 'a':'d'
'a':1:'d'

julia> typeof('a':'d')
StepRange{Char, Int64}

julia> collect('a':'d')
4-element Vector{Char}:
 'a': ASCII/Unicode U+0061 (category Ll: Letter, lowercase)
 'b': ASCII/Unicode U+0062 (category Ll: Letter, lowercase)
 'c': ASCII/Unicode U+0063 (category Ll: Letter, lowercase)
 'd': ASCII/Unicode U+0064 (category Ll: Letter, lowercase)

O tipo Char será abordado com mais detalhe noutro Conceito. Por agora, trata-os apenas como carateres isolados entre aspas simples.

Funções e operadores para ranges

Verifica os limites de um range com first() e last().

Muitas vezes é útil descobrir se um determinado valor faz parte de um range. A função subjacente para isto é in(), mas é mais comum usar o operador infixo in ou o seu sinónimo mais matemático ∈. Num editor adequado, o atalho para ∈ é \in seguido de tab.

 r = 1:10  # => 1:10
 first(r)  # => 1
 last(r)   # => 10
 7 in r    # => true
 11 ∈ r    # => false

O operador in ou ∈ é usado aqui com ranges, mas também pode ser usado com vários outros tipos de coleção, como vetores, conjuntos e dicionários.

Mais sobre a indexação de arrays

Ranges de inteiros e arrays podem ser usados na indexação de arrays:

nums = collect(10.0:50.0)
nums[3:2:7]  # gives [12.0, 14.0, 16.0]
nums[ [3, 5, 7] ] # also gives [12.0, 14.0, 16.0]

O uso com end também funciona, embora a precedência dos operadores possa exigir parênteses:

 nums[(end - 3):end]
4-element Vector{Float64}:
 47.0
 48.0
 49.0
 50.0

Claro que qualquer um dos elementos do índice pode ser uma variável inteira já existente.

Editar via GitHub A ligação abre numa nova janela ou separador

Aprende Intervalos