Ich habe eine Bedingung
if(exists && !isDirectory || !exists)
{}
Wie kann ich es ändern, damit es verständlicher wird?
exists
und isDirectory
beide wahr sind?
Ich habe eine Bedingung
if(exists && !isDirectory || !exists)
{}
Wie kann ich es ändern, damit es verständlicher wird?
exists
und isDirectory
beide wahr sind?
Antworten:
||
ist kommutativ so
if(!exists || (exists && !isDirectory))
ist gleichwertig.
Nun, weil existiert, ist es immer wahr, im zweiten Teil von ||
können Sie Folgendes fallen lassen &&
:
if(!exists || !isDirectory)
Oder Sie können noch einen Schritt weiter gehen und Folgendes tun:
if(!(exists && isDirectory))
&&
(zumindest in den meisten bekannten Sprachen - es kann Ausnahmen geben) höhere Priorität hat als ||
. Also a && b || c
ist gleichbedeutend mit (a && b) || c
aber nicht mit a && (b || c)
.
!exists || !isDirectory
ist mehr „verständlich“, weil, isDirectory
kann nicht wahr sein , wenn !exists
. Als Mensch werden wir also sagen, "wenn es nicht existiert oder [existiert und es] kein Verzeichnis ist".
||
ist nur kommutativ, wenn sie für Werte ohne Nebenwirkungen verwendet wird. Wenn sie beispielsweise für Funktionen verwendet werden, werden einige Funktionen möglicherweise nicht aufgerufen (Kurzschluss) oder geben einen anderen Wert in einer anderen Reihenfolge zurück.
Als Prozess schlage ich vor, eine Wahrheitstabelle zu erstellen:
e = exists
d = isDirectory
e | d | (e && !d) || !e
--+---+----------------
0 | 0 | 1
0 | 1 | 1
1 | 0 | 1
1 | 1 | 0
Dies entspricht der NAND
Operation , die einfach ist:
!(exists && isDirectory)
Wenn Sie sich nicht an alle Ihre Logikgatter erinnern, hat Wikipedia eine nette Referenz mit den Wahrheitstabellen .
@Christoffer Hammarström brachte einen wichtigen Punkt über den Zustand der Bindung isDirectory
an den Staatexists
. Angenommen, sie verweisen auf dieselbe Referenz und es ist nicht möglich, einen Zustand zu haben, in dem die Referenz nicht existiert und ein Verzeichnis ist, kann die Wahrheitstabelle wie folgt geschrieben werden:
e | d | (e && !d) || !e
--+---+----------------
0 | 0 | 1
0 | 1 | n/a
1 | 0 | 1
1 | 1 | 0
Das n/a
wird verwendet, um einen Zustand darzustellen, der keine Rolle spielt. Akzeptable Verringerungen könnten entweder zu 1
oder 0
für Staaten führen, die zu führen n/a
.
Mit dieser Einstellung, !(exists && isDirectory)
ist noch eine gültige Reduzierung, die zu einem 1
z !e && d
.
Es !isDirectory
wäre jedoch eine viel einfachere Reduzierung, die 0
z !e && d
.
isDirectory
ankommt exists
. Es kann nicht gleichzeitig ein Verzeichnis sein und nicht existieren.
n/a
an Stellen gefüllt werden, an denen der Zustand nicht erreicht werden kann, und die Gleichung sollte entsprechend reduziert werden.
Zur besseren Lesbarkeit extrahiere ich gerne boolesche Bedingungen in Methoden:
if(fileNameUnused())
{...}
public boolean fileNameUnused() {
return exists && !isDirectory || !exists;
}
Oder mit einem besseren Methodennamen. Wenn Sie diese Methode richtig benennen können, muss der Leser Ihres Codes nicht herausfinden, was die Boolesche Bedingung bedeutet.
boolean fileNameUnused = !exists || !isDirectory; if (fileNameUnused) { doSomething(); }
Sie könnten einfach versuchen, den No-Go- Fall zu nageln und auszusteigen, wenn das auftaucht.
while(someCondition) {
if(exists && isDirectory)
continue;
// maybe "break", depends on what you're after.
// the rest of the code
}
oder auch
function processFile(someFile)
{
// ...
if(exists && isDirectory)
return false;
// the rest of the code
// ...
}
Wie bereits erwähnt, können Sie eine Wahrheitstabelle verwenden. Der zweite Schritt könnte eine KV-Karte sein zur Minimierung der Anzahl der Begriffe sein.
Verwendung der Gesetze der Booleschen Algebra ist ein weiterer Ansatz:
A = existiert
B =! IsDirectory
! A =! Existiert
&& = *
|| = +
[Bearbeiten]
Eine einfachere Transformation, da die Operationen AND und OR sich gegenseitig verteilen:
existiert &&! isDirectory || ! existiert
= A * B +! A
= (A +! A) * (B +! A)
= 1 * (B +! A)
= B +! A
[/ Edit]
existiert &&! isDirectory || ! existiert
= A * B +! A
= A * B +! A * 1 // Identität
= A * B +! A * (B + 1) // Vernichter
= A * B +! A * B +! A / / Verteilung und Identität
= B * (A +! A) +! A // Verteilung
= B * 1 +! A // Ergänzung 2
= B +! A // Identität
=! IsDirectory || existiert
Oder mit doppeltem Komplement (!! 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 || existiert
Ich benutze nicht gerne "!" wenn der Ausdruck mehr als eine Bedingung enthält. Ich werde Codezeilen hinzufügen, um die Lesbarkeit zu verbessern.
doesNotExist = !exists;
isFile = exists && !isDirecotry;
if (isFile || doesNotExist)
{}
Wie bereits erwähnt, kann der Zustand auf Folgendes reduziert werden:
if (!(exists && isDirectory))
Ich wette jedoch, dass ein Verzeichnis Existenz impliziert. In diesem Fall können wir die Bedingung auf Folgendes reduzieren:
if (!isDirectory)