Ho una condizione
if(exists && !isDirectory || !exists)
{}
come posso modificarlo, in modo che possa essere più comprensibile.
existse isDirectorysono entrambi veri?
Ho una condizione
if(exists && !isDirectory || !exists)
{}
come posso modificarlo, in modo che possa essere più comprensibile.
existse isDirectorysono 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 || cequivale a (a && b) || cma non a a && (b || c).
!exists || !isDirectorysia più "comprensibile", perché isDirectorynon 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 NANDall'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 isDirectoryessere 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/aviene utilizzato per rappresentare uno stato che non importa. Riduzioni accettabili potrebbero comportare uno 1o entrambi gli 0stati risultanti n/a.
Con questo in mente, !(exists && isDirectory)è ancora una riduzione valida, risultante in un 1for !e && d.
Tuttavia, !isDirectorysarebbe una riduzione molto più semplice, con conseguente 0per !e && d.
isDirectorydipende da exists. Non può essere sia una directory che non esistere.
n/anei 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)