Durumu daha iyi hale getirmek için durumumu nasıl yeniden biçimlendirebilirim?


35

Bir şartım var

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

daha fazla anlaşılabilir olması için nasıl değiştirebilirim.


1
var olduğunda yanlıştır isDirectory değeri nedir?
— marktani

1
Bool tipi, isDirectory ayrıca BOOL tipi değişkenlerdir
— Spynet

5
if (! isDirectory) ... (var ||! var) her zaman doğru olacaktır.
— Shark

@Shark - Ya existsve isDirectoryher ikisi de doğrudur?
— pasawaya

Başlığı "Bir kişilik problemim var, düzeltmek için fikrimi silebilir miyim" olarak okudum. Evet, yoruldum.
— Annan

Yanıtlar:


110

|| değişmeli

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

eşdeğerdir.

Şimdi var olduğu için her zaman doğrudur, ikinci bölümünüzü ||bırakabilirsiniz &&:

if(!exists || !isDirectory)

Veya bir adım daha ileri gidip şunları yapabilirsiniz:

if(!(exists && isDirectory))

5
Burada ima edilen ancak açıkça belirtilmeyen, &&öncekinin (en azından en iyi bilinen dillerde - istisnalar olabilir) olduğundan daha yüksek önceliğe sahip olmasıdır ||. Böylece a && b || ceşittir, (a && b) || cancak değildir a && (b || c).
— Péter Török

27
Bence bu !exists || !isDirectorydaha "anlaşılabilir", çünkü isDirectoryeğer doğru olamaz !exists. Dolayısıyla bir insan olarak “eğer yoksa ya da [varsa ve bir dizin değil” diyeceğiz.
— duros

6
Ben tercih ederim! ! sonuncusu üzerinde Dizin.
— Apoorv Khurasia

3
||sadece yan etkisi olmayan değerlerde kullanılırsa değişimlidir - örneğin, işlevlerle birlikte kullanılıyorsa, bazı işlevler çağrılmayabilir (kısa devre yaptırma) veya farklı bir sırada farklı bir değer döndürme.
— orlp

26
'&&', '||', '==', '! =' 'Nin göreceli önceliğine güvenen ve parantez kullanarak niyetini netleştirmeyen herkes vurulmayı hak ediyor. Tüm dillerde, 'a && b || c 'yazarın birkaç ilave karakter yazmaktan kaçınmak için muhtemelen her şeyi aceleye getirdiğini söyleyen bir yoruma eşdeğerdir.
— Brendan

51

Bir süreç olarak bir doğruluk tablosu oluşturmayı öneriyorum:

e = exists
d = isDirectory

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

Bu basitçe NANDişlemle eşleşir :

!(exists && isDirectory)

Tüm mantık geçitlerinizi hatırlamıyorsanız, wikipedia'nin gerçek tablolarla başlatılması için güzel bir referansı var .


@Hristoffer Hammarström, devlete bağlı isDirectoryolma durumu hakkında önemli bir noktaya geldi exists. Aynı referansa başvurduklarını ve referansın bulunmadığı ve bir dizin olduğu bir duruma sahip olmanın mümkün olmadığını varsayarak , doğruluk tablosu aşağıdaki gibi yazılabilir:

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

Önemli n/aolmayan bir durumu temsil etmek için kullanılır. Kabul edilebilir indirimler, 1veya 0ile sonuçlanan devletlerde sonuçlanabilir n/a.

Bu düşünceyle, !(exists && isDirectory)bir sonuçlanan hala geçerli bir azalma olduğu 1için !e && d.

Bununla birlikte, !isDirectorysonuçta ortaya çıkan çok daha basit bir azalma 0olacaktır !e && d.


4
Bir sonraki adım bunun isDirectorybağlı olduğunu anlamaktır exists. Her ikisi de bir dizin olamaz ve olamaz.
— Christoffer Hammarström

@ChristofferHammarstrom, Bağlam dışı Değişkenlerin aynı şeyi ifade ettiğini varsaymıyorum, ama bu geçerli bir nokta. Sonuç sütunu n/a, devletin ulaşmasının imkansız olduğu yerlerde doldurulmalı ve denklem buna göre azaltılmalıdır.
— zzzzBov

Değişkenler iki farklı bağlamdan bahsediyorsa, çok özlüdür ve yeniden adlandırılmaları gerekir.
— Christoffer Hammarström

Ancak bir doğruluk tablosu oluşturmak ve değerlendirmek NP tamamlandı!
— Thomas Eding 17:12

@ThomasEding, o zaman senin için iki teklifim var, "Teoride, teoride ve pratikte aynı; pratikte, değil." ve "Erken optimizasyon tüm kötülüklerin köküdür."
— zzzzBov

22

Daha iyi okunabilirlik için, boole koşullarını yöntemlere çıkarmak isterim:

if(fileNameUnused())
{...}

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

Veya daha iyi bir yöntem adıyla. Bu yöntemi doğru şekilde adlandırabilirseniz, kodunuzun okuyucusunun boolean koşulunun ne anlama geldiğini çözmesi gerekmez.


Yararlı isimler hakkında bir şeyler söyledikleri için +1. Ama bir yerde şartlıları yeniden biçimlendirmen gerekecek.
— Apoorv Khurasia

4
Niyeti hala taşıyan daha az uç bir alternatif, sadece kullanılan koşulu adlandırmaktır:boolean fileNameUnused = !exists || !isDirectory; if (fileNameUnused) { doSomething(); }
— Steven

8

Sadece tırnak deneyebilirsiniz no-go dava ve eğer gösterileri yukarı kurtarmak.

while(someCondition) {

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

        // the rest of the code
}

ya da

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

Ayrılma, devam etme ve birden fazla dönüş ifadesi kod kokusu sayılmadı mı?
— Freiheit

8
@Freiheit Bağlama bağlıdır. Bazen, girintiyi azaltmak için okunabilirliği artıran erken bir iade ifadesi kullanılır.
— marco-fiset

En iyi cevap - karmaşık şartlandırıcılar çok fazla zaman harcarlar ve bunları doğru şekilde anlarlar. Sonuç olarak sinsi böceklere yol açan sıklıkla "okundu" olarak kabul edilir.
— mattnz

6

Belirtildiği gibi bir doğruluk tablosu kullanabilirsiniz. İkinci adım , terim sayısını en aza indirgemek için bir KV haritası olabilir .

Boolean cebirinin yasalarını kullanmak başka bir yaklaşımdır:

A = var
B =! İsDirectory
! A =! Var

&& = *
|| = +

[Düzenle]
Daha basit bir dönüşüm, çünkü AND ve OR işlemleri karşılıklı olarak dağıtılıyor:

var &&! isDirectory || ! var
= A * B +! A
= (A +! A) * (B +! A)
= 1 * (B +! A)
= B +! A
[/ Düzenle]

var &&! isDirectory || ! var
= A * B +! A
= A * B +! A * 1 // Kimlik
= A * B +! A * (B + 1) // Yok edici
= A * B +! A * B +! A / / Dağıtıcılık ve Kimlik
= B * (A +! A) +! A // Dağıtımcılık
= B * 1 +! A // Tamamlama 2
= B +! A // Kimlik
=! İsDirectory || ! mevcutsa

Veya çift tamamlayıcı ile (!! 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
=! İsDirectory || ! mevcutsa


Resmi kuralları kullanmak için + 1 (üniversitedeki ilk yılımdan sonra bunlardan birini göreceğimi asla sanmıyorum).
— Nemanja Boric


5

"!" Kullanmaktan hoşlanmıyorum. ifadesinde birden fazla koşul olduğunda. Daha okunaklı hale getirmek için kod satırları ekleyeceğim.

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

+1 Bu, İngilizce'ye çok daha yakın olan "eğer varsa veya yoksa" olarak okunmayı kolaylaştırır.
— Phil


1

Daha önce belirtildiği gibi, durum aşağıdakilere düşürülebilir:

if (!(exists && isDirectory))

Ancak, bir dizin olmanın varoluşu ima ettiğini iddia edeceğim. Eğer öyleyse, durumu şu şekilde azaltabiliriz:

if (!isDirectory)
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.