Ho una condizione
if(exists && !isDirectory || !exists)
{}
come posso modificarlo, in modo che possa essere più comprensibile.
exists
e isDirectory
sono entrambi veri?
Ho una condizione
if(exists && !isDirectory || !exists)
{}
come posso modificarlo, in modo che possa essere più comprensibile.
exists
e isDirectory
sono entrambi veri?
Risposte:
||
è commutativo così
if(!exists || (exists && !isDirectory))
è equivalente.
Ora, poiché esiste è sempre vero nella seconda parte del ||
è possibile eliminare &&
:
if(!exists || !isDirectory)
Oppure puoi fare un passo ulteriore e fare:
if(!(exists && isDirectory))
&&
ha una precedenza più alta (almeno nelle lingue più conosciute - ci possono essere eccezioni) rispetto a ||
. Quindi a && b || c
equivale a (a && b) || c
ma non a a && (b || c)
.
!exists || !isDirectory
sia più "comprensibile", perché isDirectory
non può essere vero se !exists
. Quindi come umani diremo "se non esiste o [esiste e non] non è una directory".
||
è commutativo solo se utilizzato su valori senza effetti collaterali - se ad esempio utilizzato con funzioni alcune funzioni potrebbero non essere chiamate (cortocircuito) o restituire un valore diverso in un ordine diverso.
Come processo, suggerisco di costruire una tabella di verità:
e = exists
d = isDirectory
e | d | (e && !d) || !e
--+---+----------------
0 | 0 | 1
0 | 1 | 1
1 | 0 | 1
1 | 1 | 0
Questo corrisponde NAND
all'operazione , che è semplicemente:
!(exists && isDirectory)
Se non ricordi tutte le tue porte logiche, wikipedia ha un bel riferimento con le tabelle di verità da avviare .
@Christoffer Hammarström ha sollevato un punto importante sullo stato di isDirectory
essere legato allo stato di exists
. Supponendo che si riferiscano allo stesso riferimento e che non sia possibile avere uno stato in cui il riferimento non esiste ed è una directory, la tabella di verità può essere scritta come segue:
e | d | (e && !d) || !e
--+---+----------------
0 | 0 | 1
0 | 1 | n/a
1 | 0 | 1
1 | 1 | 0
Il n/a
viene utilizzato per rappresentare uno stato che non importa. Riduzioni accettabili potrebbero comportare uno 1
o entrambi gli 0
stati risultanti n/a
.
Con questo in mente, !(exists && isDirectory)
è ancora una riduzione valida, risultante in un 1
for !e && d
.
Tuttavia, !isDirectory
sarebbe una riduzione molto più semplice, con conseguente 0
per !e && d
.
isDirectory
dipende da exists
. Non può essere sia una directory che non esistere.
n/a
nei punti in cui lo stato è impossibile da raggiungere e l'equazione ridotta di conseguenza.
Per una migliore leggibilità, mi piace estrarre condizioni booleane ai metodi:
if(fileNameUnused())
{...}
public boolean fileNameUnused() {
return exists && !isDirectory || !exists;
}
O con un nome di metodo migliore. Se riesci a nominare correttamente questo metodo, il lettore del tuo codice non ha bisogno di capire cosa significhi la condizione booleana.
boolean fileNameUnused = !exists || !isDirectory; if (fileNameUnused) { doSomething(); }
Potresti semplicemente provare a inchiodare il caso no-go e salvare se questo si presenta.
while(someCondition) {
if(exists && isDirectory)
continue;
// maybe "break", depends on what you're after.
// the rest of the code
}
o anche
function processFile(someFile)
{
// ...
if(exists && isDirectory)
return false;
// the rest of the code
// ...
}
È possibile utilizzare una tabella di verità come indicato. Il secondo passo potrebbe essere una mappa KV per ridurre al minimo il numero di termini.
L'uso delle leggi dell'algebra booleana è un altro approccio:
A = esiste
B =! IsDirectory
! A =! Esiste
&& = *
|| = +
[Modifica]
Una trasformazione più semplice, poiché le operazioni AND e OR sono reciprocamente distributive:
esiste &&! isDirectory || ! esiste
= A * B +! A
= (A +! A) * (B +! A)
= 1 * (B +! A)
= B +! A
[/ Modifica]
esiste &&! isDirectory || ! esiste
= A * B +! A
= A * B +! A * 1 // Identità
= A * B +! A * (B + 1) // Annientatore
= A * B +! A * B +! A / / Distributività e identità
= B * (A +! A) +! A // Distributività
= B * 1 +! A // Complemento 2
= B +! A // Identity
=! IsDirectory || ! esiste
O con doppio complemento (!! x = x):
A * B +! A
= !! (A * B +! A)
=! (! (A * B) * A)
=! ((! A +! B) * A)
=! (! A * A + ! B * A)
=! (0 +! B * A)
=! (! B * A)
= B +! A
=! IsDirectory || ! esiste
Non mi piace usare "!" quando c'è più di una condizione nell'espressione. Aggiungerò righe di codice per renderlo più leggibile.
doesNotExist = !exists;
isFile = exists && !isDirecotry;
if (isFile || doesNotExist)
{}
Come precedentemente indicato, la condizione può essere ridotta a:
if (!(exists && isDirectory))
Tuttavia, scommetto che essere una directory implica l'esistenza. In tal caso, possiamo ridurre la condizione a:
if (!isDirectory)