Muitas linguagens têm uma forma, como null ou none, de indicar um valor inexistente.
Como a Julia foi concebida para lidar com grandes volumes de dados (muitas vezes desorganizados), tem várias formas de representar o nada.
O objetivo geral é assinalar valores em falta ou suspeitos à medida que vão aparecendo e, depois, continuar sem lançar uma exceção.
nothingSe um valor realmente não existe, é representado por nothing. É provavelmente o mais próximo do que o C (NULL) ou o Python (None) fazem.
julia> n = nothing
julia> isnothing(n)
true
julia> typeof(n)
Nothing
Assim, nothing é um valor singleton do tipo Nothing, e podemos testá-lo.
Um uso comum de nothing é como valor devolvido (ou não valor) para funções usadas apenas pelos seus efeitos secundários (imprimir, configurar a rede, ou o que quer que seja).
missingNas situações em que um valor existe em teoria, mas não sabemos qual é, usa-se missing.
Por exemplo, ao contar veículos que circulam numa estrada, os observadores humanos podem precisar de uma pausa ou os sensores automáticos podem avariar, mas o trânsito continua a fluir.
Por isso, missing é um marcador de posição que avisa que é preciso decidir como lidar com essa falha nos dados.
julia> mv = [1, 2, missing]
3-element Vector{Union{Missing, Int64}}:
1
2
missing
julia> typeof(mv)
Vector{Union{Missing, Int64}} (alias for Array{Union{Missing, Int64}, 1})
julia> ismissing.(mv) # broadcast function, displays as 1 for true, 0 for false
3-element BitVector:
0
0
1
Poucas outras linguagens têm esta funcionalidade incorporada, mas NA em R ou NULL em SQL são equivalentes próximos.
As expressões devolvem normalmente missing por predefinição se estiverem presentes valores missing.
Se quiseres que estes valores sejam ignorados, usa a função skipmissing() para tornar isso explícito:
julia> mv = [1, 2, missing]
3-element Vector{Union{Missing, Int64}}:
1
2
missing
julia> sum(mv) # missing in, missing out
missing
julia> skipmissing(mv)
skipmissing(Union{Missing, Int64}[1, 2, missing])
julia> collect(skipmissing(mv))
2-element Vector{Int64}:
1
2
julia> sum(skipmissing(mv)) # functions like sum() can work with iterators
3
Como skipmissing cria um iterador, envolve-o em collect() se precisares de um vetor.
Por vezes, é útil substituir valores missing por um valor predefinido.
A macro @coalesce() é útil para isto, pois devolve o primeiro valor não missing (ou missing se não houver mais nenhum).
julia> str = ["I", "exist", missing]
3-element Vector{Union{Missing, String}}:
"I"
"exist"
missing
julia> [@coalesce(s, "-") for s in str]
3-element Vector{String}:
"I"
"exist"
"-"
NaNAbreviatura de «não é um número», NaN assinala um problema de cálculo em situações em que se esperava um número.
julia> v = [0, 1, -1]
3-element Vector{Int64}:
0
1
-1
julia> v / 0
3-element Vector{Float64}:
NaN
Inf
-Inf
julia> sum(v / 0)
NaN
Qualquer tipo de cálculo sobre dados que incluam um NaN dá um resultado NaN.
Atualmente não existe uma função especial para remover valores NaN, mas a função padrão filter() consegue fazê-lo de forma bastante simples.
Só os valores para os quais uma determinada condição é true são copiados para o array de resultado:
julia> filter(!isnan, [1, 2, NaN])
2-element Vector{Float64}:
1.0
2.0
Neste exercício vais escrever código para criar crachás que os funcionários da fábrica vão usar. Os funcionários têm um ID, um nome e o nome do departamento. Os rótulos dos crachás dos funcionários têm o seguinte formato: "[id] - name - DEPARTMENT".
Implementa a função print_name_badge. Deve receber um ID, um nome e um departamento. Deve devolver o rótulo do crachá, com o nome do departamento em maiúsculas.
julia> print_name_badge(67, "Katherine Williams", "Strategic Communication")
"[67] - Katherine Williams - STRATEGIC COMMUNICATION"
Devido a uma particularidade do sistema informático, os novos funcionários às vezes ainda não têm um ID quando começam a trabalhar na fábrica. Como os crachás são obrigatórios, recebem um crachá temporário sem o prefixo do ID.
Estende a função print_name_badge. Quando o ID está em falta, deve criar um crachá sem ID.
julia> print_name_badge(missing, "Robert Johnson", "Procurement")
"Robert Johnson - PROCUREMENT"
Até o proprietário da fábrica tem de usar um crachá a toda a hora. No entanto, um proprietário não tem departamento, e nunca terá: está acima de todos os departamentos. Neste caso, o rótulo deve devolver "OWNER" em vez do nome do departamento.
Estende a função print_name_badge. Quando o departamento é nothing, assume que o crachá pertence ao proprietário da empresa.
julia> print_name_badge(204, "Rachel Miller", nothing)
"[204] - Rachel Miller - OWNER"
Repara que também é possível que o proprietário seja um novo funcionário.
julia> print_name_badge(missing, "Rachel Miller", nothing)
"Rachel Miller - OWNER"
Como medida aproximada de quão bem estão a ser emitidos os IDs, queres ver o salário combinado dos funcionários sem ID. Um valor elevado significa que há muitos à espera, ou que o problema está a afetar funcionários mais antigos: as duas situações são más.
Implementa a função salaries_no_id, que recebe um vetor de IDs e um vetor correspondente de salários, e devolve a soma dos salários das pessoas que ainda não têm ID. Os dois vetores têm o mesmo comprimento.
julia> ids = [204, missing, 210, 352, missing, 263]
julia> salaries = [23, 21, 47, 35, 17, 101] * 1000
julia> salaries_no_id(ids, salaries)
38,000
Inscreve-te no Exercism para aprenderes e dominares Julia com 35 conceitos128 exercícios, e mentoria humana real, tudo grátis.