条件をより良くするためにどのように再フォーマットできますか?


35

状態がある

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

どうすれば修正できるので、より理解しやすくなります。


1
isDirectoryが存在する場合、isDirectoryの値はfalseです。
マルクタニ

1
が存在は、isDirectoryもBOOL型変数Bool型です
SpyNetの

5
if(!isDirectory)...(exists ||!exists)は常にtrueです。
サメ

@Shark -どのような場合existsisDirectoryの両方が本当ですか?
パサワヤ

タイトルに「性格の問題があります。心を消して修正できますか」と読みます。うん、疲れた。
アナン

回答:


110

|| 可換なので

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

同等です。

の2番目の部分では、existsが常に真であるため、以下||をドロップできます&&

if(!exists || !isDirectory)

または、さらに一歩進んで以下を実行できます。

if(!(exists && isDirectory))

5
ここで暗示されているが、ここで明示的に言及されていないのは、&&(少なくとも最もよく知られている言語では-例外があるかもしれない)よりも高い優先順位を持っているということです||。したがって、a && b || cと同等ですが(a && b) || c、ではありませんa && (b || c)
ペテルトーロク

27
私は、と思う!exists || !isDirectory、ので、より多くの「分かりやすい」であるisDirectory場合はtrueにすることはできません!exists。したがって、人間として「存在しないか、存在する場合はディレクトリではない」と言います。
デュロス

6
存在することを好みます|| !isDirectoryを最後のものの上に置きます。
Apoorv Khurasia

3
||副作用のない値で使用された場合にのみ可換です-たとえば関数で使用された場合、一部の関数は呼び出されない(短絡)か、異なる順序で異なる値を返します。
-orlp

26
「&&」、「||」、「==」、「!=」などの相対的な優先順位に依存し、ブラケットを使用して意図を明確にしない人は誰でも撃つに値します。すべての言語で、「a && b || c 'は、著者がいくつかの余分な文字を入力することを避けるために、おそらく急いで全体を台無しにしたというコメントに相当します。
ブレンダン

51

プロセスとして、真理値表を作成することをお勧めします。

e = exists
d = isDirectory

e | d | (e && !d) || !e
--+---+----------------
0 | 0 | 1
0 | 1 | 1
1 | 0 | 1
1 | 1 | 0

これは、単にNAND操作である操作と一致します

!(exists && isDirectory)

すべてのロジックゲートを覚えていない場合、ウィキペディアにはブートするための真理値表に関する素晴らしいリファレンスがあります


@ChristofferHammarströmは、の状態とisDirectory結びついている状態について重要なポイントを持ち出しましたexists。彼らは同じリファレンスを参照してくださいと仮定すると、それは参照が存在しない状態を持つことが可能ではないということ、次のようにディレクトリで、真理値表を書くことができます。

e | d | (e && !d) || !e
--+---+----------------
0 | 0 | 1
0 | 1 | n/a
1 | 0 | 1
1 | 1 | 0

n/a関係ない状態を表すために使用されます。許容可能な削減は、いずれか、1または0状態をもたらす可能性がありn/aます。

これを念頭に置いて、!(exists && isDirectory)まだ有効な削減であり、1forになり!e && dます。

ただし、これ!isDirectoryははるかに単純な削減であり、結果は0forになり!e && dます。


4
次のステップはにisDirectory依存することを認識することexistsです ディレクトリにすることも、存在させることもできません。
クリストファーハンマルストローム

@ChristofferHammarstrom、コンテキスト外では、変数が同じものを参照しているとは思いませんが、それは有効なポイントです。結果列はn/a、状態を達成することが不可能な場所で満たされるべきであり、それに応じて方程式は減少しました。
zzzzBov

さて、変数が2つの異なるコンテキストを参照している場合、それらは簡潔すぎるため、名前を変更する必要があります。
クリストファーハン

しかし、真理値表を作成して評価するのはNP完全です!
トーマスエディング

@ ThomasEding、2つの引用文があります。「理論的には、理論と実践は同じですが、実際にはそうではありません。」「早すぎる最適化はすべての悪の根源です。」
zzzzBov

22

読みやすくするために、メソッドにブール条件を抽出します。

if(fileNameUnused())
{...}

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

または、より良いメソッド名で。このメソッドに適切な名前を付けることができれば、コードの読者はブール条件の意味を理解する必要がありません。


便利な名前について何かを言うと+1。しかし、どこかで条件を再フォーマットする必要があります。
Apoorv Khurasia

4
まだ意思伝えるあまり極端な代替手段は、単に条件に名前を付けるために使用されます:boolean fileNameUnused = !exists || !isDirectory; if (fileNameUnused) { doSomething(); }
スティーブン・

8

ノーゴーケースを釘付けにして、それが現れたら救済することができます。

while(someCondition) {

    if(exists && isDirectory)
        continue;
        // maybe "break", depends on what you're after.

        // the rest of the code
}

あるいは

function processFile(someFile)
{ 
    // ...
    if(exists && isDirectory)
       return false;
    // the rest of the code
    // ...
}

壊れて、続けて、コードのにおいを考慮した複数のreturnステートメントはありませんか?
フライハイト

8
@Freiheitコンテキストに依存します。インデントを減らすために、早期のreturnステートメントが使用されることがあり、読みやすさが向上します。
marco-fiset

ベストアンサー-複雑な条件は、膨大な時間を読み、それらを正確に理解するのに無駄です。その結果、多くの場合、「読まれたと見なされて」、潜在的なバグが発生します。
mattnz

6

指摘したとおり、真理値表を使用できます。2番目のステップは、項の数を最小化するためのKVマップです。

ブール代数の法則を使用することも別のアプローチです。

A =存在する
B =!isDirectory
!A =!exists

&& = *
|| = +

[編集]
操作ANDとORは相互に分配的であるため、より単純な変換です。

存在する&&!isDirectory || !exists
= A * B +!A
=(A +!A)*(B +!A)
= 1 *(B +!A)
= B +!A
[/編集]

存在する&&!isDirectory || !exists
= A * B +!A
= A * B +!A * 1 // ID
= A * B +!A *(B + 1)// Annihilator
= A * B +!A * B +!A / / Distributivity and Identity
= B *(A +!A)+!A // Distributivity
= B * 1 +!A // Complementation 2
= B +!A // Identity
=!isDirectory || 存在する

または、二重補数(!! 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 || 存在する


正式なルールを使用するための+1(私は大学の最初の1年後にこれらのいずれかを見ることはありませんが)。
ネマンジャボリック


5

「!」を使用したくない 式に複数の条件がある場合。より読みやすくするためにコード行を追加します。

doesNotExist = !exists;
isFile = exists && !isDirecotry;
if (isFile || doesNotExist) 
   {}

+1これにより、「ファイルが存在する場合または存在しない場合」として読みやすくなります。
フィル

これは、変数の説明と呼ばれるリファクタリングです。
エディガスパリアン

1

前述のように、条件は次のように縮小できます。

if (!(exists && isDirectory))

ただし、ディレクトリであることは存在を意味するに違いないと思います。その場合、条件を次のように減らすことができます。

if (!isDirectory)
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.