tengo una condición
if(exists && !isDirectory || !exists)
{}
¿Cómo puedo modificarlo para que sea más comprensible?
existsy isDirectoryson ambas verdaderas?
tengo una condición
if(exists && !isDirectory || !exists)
{}
¿Cómo puedo modificarlo para que sea más comprensible?
existsy isDirectoryson ambas verdaderas?
Respuestas:
|| es conmutativo así
if(!exists || (exists && !isDirectory))
es equivalente.
Ahora porque existe siempre es cierto en la segunda parte de la ||que puede soltar &&:
if(!exists || !isDirectory)
O puede ir un paso más allá y hacer:
if(!(exists && isDirectory))
&&tiene mayor prioridad (al menos en la mayoría de los idiomas conocidos, puede haber excepciones) que ||. Por a && b || clo tanto, es equivalente (a && b) || cpero no a a && (b || c).
!exists || !isDirectoryes más "comprensible", porque isDirectoryno puede ser cierto si !exists. Entonces, como humanos diremos "si no existe o si [existe y no] es un directorio".
||solo es conmutativo si se usa en valores sin efectos secundarios; si, por ejemplo, se usa con funciones, algunas funciones podrían no llamarse (cortocircuito) o devolver un valor diferente en un orden diferente.
Como proceso, sugiero construir una tabla de verdad:
e = exists
d = isDirectory
e | d | (e && !d) || !e
--+---+----------------
0 | 0 | 1
0 | 1 | 1
1 | 0 | 1
1 | 1 | 0
Esto coincide con la NANDoperación , que es simplemente:
!(exists && isDirectory)
Si no recuerda todas sus puertas lógicas, wikipedia tiene una buena referencia con las tablas de verdad para arrancar .
@Christoffer Hammarström planteó un punto importante sobre el estado de isDirectoryestar vinculado al estado de exists. Suponiendo que se refieren a la misma referencia, y que no es posible tener un estado donde la referencia no existe y es un directorio, la tabla de verdad se puede escribir de la siguiente manera:
e | d | (e && !d) || !e
--+---+----------------
0 | 0 | 1
0 | 1 | n/a
1 | 0 | 1
1 | 1 | 0
El n/ase utiliza para representar un estado que no importa. Reducciones aceptables podrían resultar en 1o 0para los estados resultantes en n/a.
Con esto en mente, !(exists && isDirectory)sigue siendo una reducción válida, lo que resulta en un 1for !e && d.
Sin embargo, !isDirectorysería una reducción mucho más simple, lo que resulta en 0para !e && d.
isDirectorydepende exists. No puede ser un directorio y no existir.
n/aen lugares donde el estado es imposible de alcanzar, y la ecuación debe reducirse en consecuencia.
Para una mejor legibilidad, me gusta extraer condiciones booleanas a los métodos:
if(fileNameUnused())
{...}
public boolean fileNameUnused() {
return exists && !isDirectory || !exists;
}
O con un mejor nombre de método. Si puede nombrar este método correctamente, el lector de su código no necesita descubrir qué significa la condición booleana.
boolean fileNameUnused = !exists || !isDirectory; if (fileNameUnused) { doSomething(); }
Podrías tratar de arreglar el caso de no ir y rescatar si eso aparece.
while(someCondition) {
if(exists && isDirectory)
continue;
// maybe "break", depends on what you're after.
// the rest of the code
}
o incluso
function processFile(someFile)
{
// ...
if(exists && isDirectory)
return false;
// the rest of the code
// ...
}
Puede usar una tabla de verdad como se señaló. El segundo paso podría ser un mapa KV para minimizar el número de términos.
Usar las leyes del álgebra booleana es otro enfoque:
A = existe
B =! IsDirectory
! A =! Existe
&& = *
|| = +
[Editar]
Una transformación más simple, porque las operaciones AND y OR son mutuamente distributivas:
existe &&! isDirectory || ! existe
= A * B +! A
= (A +! A) * (B +! A)
= 1 * (B +! A)
= B +! A
[/ Editar]
existe &&! isDirectory || ! existe
= A * B +! A
= A * B +! A * 1 // Identidad
= A * B +! A * (B + 1) // Aniquilador
= A * B +! A * B +! A / / Distributividad e identidad
= B * (A +! A) +! A // Distributividad
= B * 1 +! A // Complementación 2
= B +! A // Identidad
=! IsDirectory || ! existe
O con doble 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 || ! existe
No me gusta usar "!" cuando hay más de una condición en la expresión. Agregaré líneas de código para hacerlo más legible.
doesNotExist = !exists;
isFile = exists && !isDirecotry;
if (isFile || doesNotExist)
{}
Como se indicó anteriormente, la condición se puede reducir a:
if (!(exists && isDirectory))
Sin embargo, apuesto a que ser un directorio implica existencia. Si es así, podemos reducir la condición a:
if (!isDirectory)