Mam warunek
if(exists && !isDirectory || !exists)
{}
jak mogę go zmodyfikować, aby był bardziej zrozumiały.
existsi isDirectoryczy oba są prawdziwe?
Mam warunek
if(exists && !isDirectory || !exists)
{}
jak mogę go zmodyfikować, aby był bardziej zrozumiały.
existsi isDirectoryczy oba są prawdziwe?
Odpowiedzi:
|| jest więc przemienny
if(!exists || (exists && !isDirectory))
jest równoważne.
Teraz, ponieważ istnieje jest zawsze prawdziwe w drugiej części ||możesz upuścić &&:
if(!exists || !isDirectory)
Możesz też pójść o krok dalej i zrobić:
if(!(exists && isDirectory))
&&ma wyższy priorytet (przynajmniej w najbardziej znanych językach - mogą istnieć wyjątki) niż ||. a && b || cJest to więc równoważne, (a && b) || cale nie a && (b || c).
!exists || !isDirectoryjest to bardziej „zrozumiałe”, ponieważ isDirectorynie może być prawdą, jeśli !exists. Więc jako człowiek powiemy „jeśli nie istnieje lub [istnieje i nie jest katalogiem”.
||jest przemienny tylko wtedy, gdy jest stosowany w przypadku wartości bez skutków ubocznych - jeśli na przykład jest używany z funkcjami, niektóre funkcje mogą nie zostać wywołane (zwarcie) lub zwrócić inną wartość w innej kolejności.
Jako proces sugeruję zbudowanie tabeli prawdy:
e = exists
d = isDirectory
e | d | (e && !d) || !e
--+---+----------------
0 | 0 | 1
0 | 1 | 1
1 | 0 | 1
1 | 1 | 0
Jest to zgodne z NANDoperacją , która jest po prostu:
!(exists && isDirectory)
Jeśli nie pamiętasz wszystkich swoich bramek logicznych, wikipedia ma ładny odnośnik z tabelami prawdy do uruchomienia .
@Christoffer Hammarström poruszył ważną kwestię dotyczącą stanu isDirectoryprzywiązania do tego stanu exists. Zakładając, że odnoszą się do tego samego odwołania i że nie jest możliwe, aby stan, w którym odwołanie nie istnieje i jest katalogiem, tabelę prawdy można zapisać w następujący sposób:
e | d | (e && !d) || !e
--+---+----------------
0 | 0 | 1
0 | 1 | n/a
1 | 0 | 1
1 | 1 | 0
n/aJest używany do reprezentowania stanu, że nie ma znaczenia. Dopuszczalne redukcje mogą skutkować skutkiem jednego 1lub obu 0stanów n/a.
Mając to na uwadze, !(exists && isDirectory)nadal obowiązuje ważna redukcja, w wyniku której powstaje 1for !e && d.
Jednak !isDirectorybyłoby o wiele prostsze redukcji, w wyniku czego 0na !e && d.
isDirectoryzależy exists. Nie może być jednocześnie katalogiem i nie istnieje.
n/aw miejscach, w których nie można osiągnąć stanu, a równanie odpowiednio zmniejszyć.
Dla lepszej czytelności lubię wyodrębniać warunki boolowskie do metod:
if(fileNameUnused())
{...}
public boolean fileNameUnused() {
return exists && !isDirectory || !exists;
}
Lub z lepszą nazwą metody. Jeśli potrafisz poprawnie nazwać tę metodę, czytnik twojego kodu nie musi odgadnąć, co oznacza warunek logiczny.
boolean fileNameUnused = !exists || !isDirectory; if (fileNameUnused) { doSomething(); }
Możesz po prostu spróbować przybić skrzynkę no-go i wpłacić kaucję, jeśli się pojawi.
while(someCondition) {
if(exists && isDirectory)
continue;
// maybe "break", depends on what you're after.
// the rest of the code
}
lub nawet
function processFile(someFile)
{
// ...
if(exists && isDirectory)
return false;
// the rest of the code
// ...
}
Możesz użyć tabeli prawdy, jak wskazano. Drugim krokiem może być mapa KV dla zminimalizowania liczby terminów.
Korzystanie z praw algebry boolowskiej to kolejne podejście:
A = istnieje
B =! IsDirectory
! A =! Istnieje
&& = *
|| = +
[Edytuj]
Prostsza transformacja, ponieważ operacje AND i OR dzielą się wzajemnie:
istnieje &&! isDirectory || ! istnieje
= A * B +! A
= (A +! A) * (B +! A)
= 1 * (B +! A)
= B +! A
[/ Edytuj]
istnieje &&! isDirectory || ! istnieje
= A * B +! A
= A * B +! A * 1 // Tożsamość
= A * B +! A * (B + 1) // Annihilator
= A * B +! A * B +! A / / Dystrybucja i tożsamość
= B * (A +! A) +! A // Dystrybucja
= B * 1 +! A // Uzupełnienie 2
= B +! A // Tożsamość
=! IsDirectory || ! istnieje
Lub z podwójnym uzupełnieniem (!! 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 || ! istnieje
Nie lubię używać „!” gdy w wyrażeniu występuje więcej niż jeden warunek. Dodam wiersze kodu, aby był bardziej czytelny.
doesNotExist = !exists;
isFile = exists && !isDirecotry;
if (isFile || doesNotExist)
{}
Jak wskazano wcześniej, warunek można sprowadzić do:
if (!(exists && isDirectory))
Założę się jednak, że bycie katalogiem oznacza istnienie. Jeśli tak, możemy zredukować ten warunek do:
if (!isDirectory)