Eu tenho uma condição
if(exists && !isDirectory || !exists)
{}
como posso modificá-lo, para que seja mais compreensível.
exists
e isDirectory
são verdadeiras?
Eu tenho uma condição
if(exists && !isDirectory || !exists)
{}
como posso modificá-lo, para que seja mais compreensível.
exists
e isDirectory
são verdadeiras?
Respostas:
||
é comutativo, então
if(!exists || (exists && !isDirectory))
é equivalente.
Agora, porque existe sempre é verdade na segunda parte do, ||
você pode soltar o &&
:
if(!exists || !isDirectory)
Ou você pode dar um passo adiante e fazer:
if(!(exists && isDirectory))
&&
tem maior precedência (pelo menos na maioria dos idiomas conhecidos - pode haver exceções) ||
. Assim, a && b || c
é equivalente a, (a && b) || c
mas não a a && (b || c)
.
!exists || !isDirectory
é mais "compreensível", porque, isDirectory
não pode ser verdade se !exists
. Então, como humano, diremos "se ele não existe ou se existe e não é um diretório".
||
é comutativo apenas se usado em valores sem efeitos colaterais - se, por exemplo, usado com funções, algumas funções podem não ser chamadas (curto-circuito) ou retornar um valor diferente em uma ordem diferente.
Como processo, sugiro construir uma tabela de verdade:
e = exists
d = isDirectory
e | d | (e && !d) || !e
--+---+----------------
0 | 0 | 1
0 | 1 | 1
1 | 0 | 1
1 | 1 | 0
Isso corresponde à NAND
operação , que é simplesmente:
!(exists && isDirectory)
Se você não se lembra de todos os seus portais lógicos, a wikipedia tem uma boa referência com as tabelas da verdade para inicializar .
@Christoffer Hammarström levantou um ponto importante sobre o estado de isDirectory
amarração ao estado de exists
. Supondo que eles se refiram à mesma referência e que não é possível ter um estado em que a referência não exista e seja um diretório, a tabela verdade pode ser escrita da seguinte maneira:
e | d | (e && !d) || !e
--+---+----------------
0 | 0 | 1
0 | 1 | n/a
1 | 0 | 1
1 | 1 | 0
O n/a
é usado para representar um estado que não importa. Reduções aceitáveis podem resultar em um 1
ou 0
para os estados que resultam em n/a
.
Com isso em mente, !(exists && isDirectory)
ainda é uma redução válida, resultando em um 1
para !e && d
.
No entanto, !isDirectory
seria uma redução muito mais simples, resultando em 0
para !e && d
.
isDirectory
depende exists
. Não pode ser um diretório e não existir.
n/a
em locais onde o estado é impossível de alcançar e a equação reduzida em conformidade.
Para melhor legibilidade, eu gosto de extrair condições booleanas para métodos:
if(fileNameUnused())
{...}
public boolean fileNameUnused() {
return exists && !isDirectory || !exists;
}
Ou com um nome de método melhor. Se você pode nomear esse método corretamente, o leitor do seu código não precisa descobrir o que significa a condição booleana.
boolean fileNameUnused = !exists || !isDirectory; if (fileNameUnused) { doSomething(); }
Você pode apenas tentar acertar o caso de não-ir e sair se isso aparecer.
while(someCondition) {
if(exists && isDirectory)
continue;
// maybe "break", depends on what you're after.
// the rest of the code
}
ou mesmo
function processFile(someFile)
{
// ...
if(exists && isDirectory)
return false;
// the rest of the code
// ...
}
Você pode usar uma tabela verdade, conforme indicado. O segundo passo pode ser um mapa KV para minimizar o número de termos.
Usar as leis da álgebra booleana é outra abordagem:
A = existe
B =! IsDirectory
! A =! Existe
&& = *
|| = +
[Editar]
Uma transformação mais simples, porque as operações AND e OR são mutuamente distributivas:
existe o &&! isDirectory || ! existe
= A * B +! A
= (A +! A) * (B +! A)
= 1 * (B +! A)
= B +! A
[/ Edit]
existe o &&! isDirectory || ! existe
= A * B +! A
= A * B +! A * 1 // Identidade
= A * B +! A * (B + 1) // Annihilator
= A * B +! A * B +! A / / Distribuutividade e identidade
= B * (A +! A) +! A // Distributividade
= B * 1 +! A // Complementação 2
= B +! A // Identidade
=! IsDirectory || !existe
Ou com complemento duplo (!! 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 || !existe
Eu não gosto de usar "!" quando houver mais de uma condição na expressão. Vou adicionar linhas de código para torná-lo mais legível.
doesNotExist = !exists;
isFile = exists && !isDirecotry;
if (isFile || doesNotExist)
{}
Conforme indicado anteriormente, a condição pode ser reduzida para:
if (!(exists && isDirectory))
No entanto, aposto que ser um diretório implica existência. Nesse caso, podemos reduzir a condição para:
if (!isDirectory)