Saya memiliki suatu kondisi
if(exists && !isDirectory || !exists)
{}
bagaimana saya bisa memodifikasinya, sehingga bisa lebih dimengerti.
exists
dan isDirectory
keduanya benar?
Saya memiliki suatu kondisi
if(exists && !isDirectory || !exists)
{}
bagaimana saya bisa memodifikasinya, sehingga bisa lebih dimengerti.
exists
dan isDirectory
keduanya benar?
Jawaban:
||
komutatif begitu
if(!exists || (exists && !isDirectory))
setara.
Sekarang karena ada selalu benar di bagian kedua ||
Anda dapat menjatuhkan &&
:
if(!exists || !isDirectory)
Atau Anda dapat melangkah lebih jauh dan melakukan:
if(!(exists && isDirectory))
&&
memiliki prioritas lebih tinggi (setidaknya dalam sebagian besar bahasa terkenal - mungkin ada pengecualian) daripada ||
. Jadi a && b || c
sama dengan (a && b) || c
tetapi tidak untuk a && (b || c)
.
!exists || !isDirectory
lebih "dapat dimengerti", karena, isDirectory
tidak mungkin benar jika !exists
. Jadi sebagai manusia kita akan mengatakan "jika itu tidak ada atau itu [ada dan itu] bukan direktori".
||
hanya komutatif jika digunakan pada nilai tanpa efek samping - jika misalnya digunakan dengan fungsi, beberapa fungsi mungkin tidak dipanggil (hubungan arus pendek) atau mengembalikan nilai yang berbeda dalam urutan yang berbeda.
Sebagai suatu proses, saya sarankan membangun tabel kebenaran:
e = exists
d = isDirectory
e | d | (e && !d) || !e
--+---+----------------
0 | 0 | 1
0 | 1 | 1
1 | 0 | 1
1 | 1 | 0
Ini cocok dengan NAND
operasi , yang hanya:
!(exists && isDirectory)
Jika Anda tidak mengingat semua gerbang logika Anda, wikipedia memiliki referensi yang bagus dengan tabel kebenaran untuk di-boot .
@Christoffer Hammarström mengemukakan satu poin penting tentang keadaan isDirectory
terikat pada keadaan exists
. Dengan asumsi bahwa mereka merujuk ke referensi yang sama, dan bahwa tidak mungkin memiliki keadaan di mana referensi tidak ada dan merupakan direktori, tabel kebenaran dapat ditulis sebagai berikut:
e | d | (e && !d) || !e
--+---+----------------
0 | 0 | 1
0 | 1 | n/a
1 | 0 | 1
1 | 1 | 0
Yang n/a
digunakan untuk mewakili sebuah negara yang tidak peduli. Pengurangan yang dapat diterima dapat menghasilkan salah satu 1
atau 0
untuk negara bagian yang menghasilkan n/a
.
Dengan pemikiran ini, !(exists && isDirectory)
masih merupakan reduksi yang valid, menghasilkan 1
for !e && d
.
Namun, !isDirectory
pengurangan akan jauh lebih sederhana, menghasilkan 0
untuk !e && d
.
isDirectory
tergantung pada exists
. Keduanya tidak bisa berupa direktori dan tidak ada.
n/a
tempat-tempat di mana negara tidak mungkin untuk dicapai, dan persamaan berkurang sesuai.
Untuk keterbacaan yang lebih baik, saya suka mengekstraksi kondisi boolean ke metode:
if(fileNameUnused())
{...}
public boolean fileNameUnused() {
return exists && !isDirectory || !exists;
}
Atau dengan nama metode yang lebih baik. Jika Anda dapat memberi nama metode ini dengan benar, pembaca kode Anda tidak perlu mencari tahu apa arti kondisi boolean.
boolean fileNameUnused = !exists || !isDirectory; if (fileNameUnused) { doSomething(); }
Anda bisa mencoba untuk menyelesaikan kasus no-go dan menebus jika itu muncul.
while(someCondition) {
if(exists && isDirectory)
continue;
// maybe "break", depends on what you're after.
// the rest of the code
}
atau bahkan
function processFile(someFile)
{
// ...
if(exists && isDirectory)
return false;
// the rest of the code
// ...
}
Anda bisa menggunakan tabel kebenaran seperti yang ditunjukkan. Langkah kedua bisa berupa peta KV untuk meminimalkan jumlah istilah.
Menggunakan hukum aljabar Boolean adalah pendekatan lain:
A = ada
B =! IsDirectory
! A =! Ada
&& = *
|| = +
[Sunting]
Transformasi yang lebih sederhana, karena operasi AND dan OR saling mendistribusikan:
ada &&! isDirectory || ! exist
= A * B +! A
= (A +! A) * (B +! A)
= 1 * (B +! A)
= B +! A
[/ Edit]
ada &&! isDirectory || ! exist
= A * B +! A
= A * B +! A * 1 // Identitas
= A * B +! A * (B + 1) // Annihilator
= A * B +! A * B +! A / / Distributivity and Identity
= B * (A +! A) +! A // Distributivity
= B * 1 +! A // Komplementasi 2
= B +! A // Identity
=! IsDirectory || ! ada
Atau dengan komplemen ganda (!! 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 || ! ada
Saya tidak suka menggunakan "!" ketika ada lebih dari satu syarat dalam ekspresi. Saya akan menambahkan baris kode agar lebih mudah dibaca.
doesNotExist = !exists;
isFile = exists && !isDirecotry;
if (isFile || doesNotExist)
{}
Seperti yang ditunjukkan sebelumnya, kondisinya dapat dikurangi menjadi:
if (!(exists && isDirectory))
Namun, saya berani bertaruh bahwa menjadi direktori berarti keberadaan. Jika demikian, kita dapat mengurangi kondisinya menjadi:
if (!isDirectory)