Come posso riformattare la mia condizione per renderla migliore?

35

Ho una condizione

if(exists && !isDirectory || !exists)
{}

come posso modificarlo, in modo che sia più comprensibile.

    
posta Spynet 05.10.2012 - 13:54
fonte

7 risposte

110

|| è commutativo quindi

if(!exists || (exists && !isDirectory))

è equivalente.

Ora perché esiste è sempre true nella seconda parte di || puoi eliminare && :

if(!exists || !isDirectory)

Oppure puoi fare un ulteriore passo avanti e fare:

if(!(exists && isDirectory))
    
risposta data 05.10.2012 - 14:04
fonte
51

Come procedura, ti suggerisco di creare 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

Corrisponde all'operazione NAND , che è semplicemente:

!(exists && isDirectory)

Se non ricordi tutte le porte logiche, wikipedia ha un buon riferimento con le tabelle di verità da avviare .

@Christoffer Hammarström ha sollevato un punto importante sullo stato di isDirectory 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 e è 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 ha importanza. Riduzioni accettabili potrebbero comportare 1 o 0 per gli stati che risultano in n/a .

Con questo in mente, !(exists && isDirectory) è ancora una riduzione valida, con conseguente 1 per !e && d .

Tuttavia, !isDirectory sarebbe una riduzione molto più semplice, risultante in 0 per !e && d .

    
risposta data 05.10.2012 - 19:57
fonte
22

Per una migliore leggibilità, mi piace estrapolare le condizioni booleane ai metodi:

if(fileNameUnused())
{...}

public boolean fileNameUnused() {
   return exists && !isDirectory || !exists;
}

O con un nome di metodo migliore. Se riesci a denominare correttamente questo metodo, il lettore del tuo codice non ha bisogno di capire cosa significhi la condizione booleana.

    
risposta data 05.10.2012 - 14:21
fonte
8

Potresti provare a inchiodare il caso no-go e salvarlo se viene visualizzato.

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
    // ...
}
    
risposta data 05.10.2012 - 14:44
fonte
6

Puoi usare una tabella di verità come indicato. Il secondo passaggio potrebbe essere una KV-map per ridurre al minimo il numero di termini.

L'utilizzo delle leggi di l'algebra booleana è un altro approccio:

A = esiste
B =! IsDirectory
! A =! Esiste

& & = *
|| = +

[Edit]
Una trasformazione più semplice, perché le operazioni AND e OR sono reciprocamente distributive:

esiste & & ! isDirectory || ! Esiste
= A * B +! A
= (A +! A) * (B +! A)
= 1 * (B +! A)
= B +! A
[/ Edit]

esiste & & ! isDirectory || ! Esiste
= A * B +! A
= A * B +! A * 1 // Identità
= A * B +! A * (B + 1) // Annihilator
= A * B +! A * B +! A // Distributività e identità
= B * (A +! A) +! A // Distributività
= B * 1 +! A // Complementazione 2
= B +! A // Identità
=! 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

    
risposta data 05.10.2012 - 22:59
fonte
5

Non mi piace usare "!" quando c'è più di una condizione nell'espressione. Aggiungerò linee di codice per renderlo più leggibile.

doesNotExist = !exists;
isFile = exists && !isDirecotry;
if (isFile || doesNotExist) 
   {}
    
risposta data 06.10.2012 - 00:06
fonte
1

Come indicato in precedenza, la condizione può essere ridotta a:

if (!(exists && isDirectory))

Tuttavia, scommetto che essere una directory implica esistenza. Se è così, possiamo ridurre la condizione a:

if (!isDirectory)
    
risposta data 06.10.2012 - 18:23
fonte

Leggi altre domande sui tag