Molti linguaggi hanno un modo, come null o none, per indicare un valore inesistente.
Poiché Julia è progettato per gestire grandi quantità di dati (spesso disordinati), ha diverse forme di nulla.
L'obiettivo generale è segnalare i valori mancanti o sospetti man mano che si incontrano, per poi continuare senza sollevare un'eccezione.
nothingSe un valore non esiste davvero, viene rappresentato con nothing. È probabilmente la cosa più vicina a quello che fanno NULL in C o None in Python.
julia> n = nothing
julia> isnothing(n)
true
julia> typeof(n)
Nothing
Quindi nothing è un valore singleton di tipo Nothing, e possiamo verificarlo.
Un uso comune di nothing è come valore di ritorno (o non-valore) per le funzioni che servono solo per i loro effetti collaterali (stampa, configurazione di rete, o qualsiasi altra cosa).
missingNelle situazioni in cui un valore esiste in teoria ma non sappiamo quale sia, si usa missing.
Per esempio, quando si contano i veicoli che viaggiano su una strada, gli osservatori umani possono aver bisogno di una pausa oppure i sensori automatici possono guastarsi, ma il traffico continua a scorrere.
Quindi missing è un segnaposto: avverte che bisogna decidere come gestire questa lacuna nei dati.
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
Pochi altri linguaggi hanno questa funzionalità integrata, ma esistono analoghi simili: NA in R o NULL in SQL.
Di solito le espressioni restituiscono missing quando sono presenti valori missing.
Se vuoi che questi valori vengano ignorati, usa la funzione skipmissing() per renderlo esplicito:
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
Poiché skipmissing crea un iteratore, avvolgilo in collect() se ti serve un vettore.
A volte è utile sostituire i valori missing con un valore predefinito.
La macro @coalesce() è utile a questo scopo, perché restituisce il primo valore che non è missing (o missing se non c'è altro).
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"
"-"
NaNAbbreviazione di «Not a Number», NaN segnala un problema di calcolo nelle situazioni in cui ci si aspettava un numero.
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
Qualsiasi tipo di calcolo su dati che includono un NaN darà come risultato NaN.
Al momento non esiste una funzione speciale per rimuovere i valori NaN, ma la funzione standard filter() può farlo in modo piuttosto semplice.
Vengono copiati nell'array risultante solo i valori per cui una data condizione è true:
julia> filter(!isnan, [1, 2, NaN])
2-element Vector{Float64}:
1.0
2.0
In questo esercizio scriverai il codice per creare badge con il nome che i dipendenti della fabbrica devono indossare. I dipendenti hanno un ID, un nome e il nome del reparto. Le etichette dei badge dei dipendenti sono formattate come segue: "[id] - name - DEPARTMENT".
Implementa la funzione print_name_badge. Deve accettare un ID, un nome e un reparto. Deve restituire l'etichetta del badge, con il nome del reparto in maiuscolo.
julia> print_name_badge(67, "Katherine Williams", "Strategic Communication")
"[67] - Katherine Williams - STRATEGIC COMMUNICATION"
A causa di una stranezza del sistema informatico, a volte i nuovi dipendenti non hanno ancora un ID quando iniziano a lavorare in fabbrica. Dato che i badge sono obbligatori, riceveranno un badge temporaneo senza il prefisso dell'ID.
Estendi la funzione print_name_badge. Quando l'ID manca, deve creare un badge senza ID.
julia> print_name_badge(missing, "Robert Johnson", "Procurement")
"Robert Johnson - PROCUREMENT"
Persino il proprietario della fabbrica deve indossare un badge in ogni momento. Tuttavia, un proprietario non ha un reparto e non ne avrà mai: è al di sopra di tutti i reparti. In questo caso, l'etichetta deve restituire "OWNER" al posto del nome del reparto.
Estendi la funzione print_name_badge. Quando il reparto è nothing, supponi che il badge appartenga al proprietario dell'azienda.
julia> print_name_badge(204, "Rachel Miller", nothing)
"[204] - Rachel Miller - OWNER"
Nota che è possibile che il proprietario sia anche un nuovo dipendente.
julia> print_name_badge(missing, "Rachel Miller", nothing)
"Rachel Miller - OWNER"
Come misura approssimativa di quanto bene vengono assegnati gli ID, vuoi vedere lo stipendio complessivo dei dipendenti senza ID. Un valore alto significa che molti sono in attesa, oppure che il problema riguarda anche le persone con più anzianità: entrambe le cose sono negative.
Implementa la funzione salaries_no_id che accetta un vettore di ID e un vettore corrispondente di stipendi, e restituisce la somma degli stipendi delle persone che non hanno ancora un ID. Entrambi i vettori hanno la stessa lunghezza.
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
Iscriviti a Exercism per imparare e padroneggiare Julia con 35 concetti128 esercizi e il mentoring di persone reali, tutto gratis.