Write in front
Due to the power outage in the test room in the past two days, there is nothing to do in these two days, so what are you doing? Thinking about whether or not to try to write another article to chat. So there is today's article.
Origin of the topic
Last month, someone in the community asked such a question-how to simplify the JS judgment of
const isDel = (op, o) => {
let fal = false;
if (op.is_show_lock && op.is_show_sf && op.is_show_bz) {
if (o.is_lock && o.is_sf && o.is_bz) {
fal = false;
} else {
fal = true;
}
} else if (op.is_show_lock && op.is_show_sf) {
if (o.is_lock && o.is_sf) {
fal = false;
} else {
fal = true;
}
} else if (op.is_show_lock && op.is_show_bz) {
if (o.is_lock && o.is_bz) {
fal = false;
} else {
fal = true;
}
} else if (op.is_show_sf && op.is_show_bz) {
if (o.is_sf && o.is_bz) {
fal = false;
} else {
fal = true;
}
} else if (op.is_show_lock) {
if (o.is_lock) {
fal = false;
} else {
fal = true;
}
} else if (op.is_show_sf) {
if (o.is_sf) {
fal = false;
} else {
fal = true;
}
} else if (op.is_show_bz) {
if (o.is_bz) {
fal = false;
} else {
fal = true;
}
}
return fal;
};
It can be seen that the main logic of this code is to determine the final result and output a Boolean value based on several fields. In the end, the answer given by the author is -
const isRemove = (op, o) => (op.is_show_lock && !o.is_lock) || (op.is_show_sf && !o.is_sf) || (op.is_show_bz && !o.is_bz)
So how do I simplify it? When looking at the above long list of logical judgments, it is obvious that there are too many repeated use of fields. The author's first feeling is that Boolean algebra should be used to simplify it. There are two knowledge points involved here, Boolean algebra law and laws of Boolean algebra , on both theoretical knowledge do not go into details, you can click on the link to view or use the search engine used to search for access to relevant information. We go directly to the topic.
simplify
First of all, we can review the code of the subject under the subject that there are fewer conditions to meet true [ps: because false not only includes the conditions in if, but also includes the case where else is not met. This is the first time the author answered incorrectly. Time bug], then list all Boolean expressions that satisfy true as follows:
op.is_show_lock && op.is_show_sf && op.is_show_bz && !(o.is_lock && o.is_sf && o.is_bz) ||
op.is_show_lock && op.is_show_sf && !(o.is_lock && o.is_sf) ||
op.is_show_lock && op.is_show_bz && !(o.is_lock && o.is_bz) ||
op.is_show_sf && op.is_show_bz && !(o.is_sf && o.is_bz) ||
op.is_show_lock && !o.is_lock ||
op.is_show_sf && !o.is_sf ||
op.is_show_bz && !o.is_bz
The field is just a representation, so letters can be used instead to simplify the expression. Assumption:
op.is_show_lock -> A
op.is_show_sf -> B
op.is_show_bz -> C
o.is_lock -> a
o.is_show_lock -> b
o.is_show_lock -> c
And because it is expressed as a mathematical language, in mathematics:
&& -> ·
|| -> +
! -> ′
Therefore, the code is expressed as the following Boolean algebra:
A · B · C · (a · b · c)′ +
A · B · (a · b)′ +
A · C · (a · c)′ +
B · C · (b · c)′ +
A · a′ +
B · b′ +
C · c′
The next step is to apply the Boolean operation law to this Boolean algebra to simplify it to get the final optimal Boolean algebra.
step
De Morgan's law (inversion law): (a+b)′=a′·b′, (a·b)′=a′+b′.
A · B · C · (a′ + b′ + c′) + A · B · (a′ + b′) + A · C · (a′ + c′) + B · C · (b′ + c′) + A · a′ + B · b′ + C · c′
Distribution law: a·(b+c)=(a·b)+(a·c), (a+b)·c=(a·c)+(b·c)
From the result of step 1, it can be seen that allabc
area′b′c′
, then we will make another substitution here, each expressed asxyz
; then according to the distribution law, we can get:A · B · C · x + A · B · C · y + A · B · C · z + A · B · x + A · B · y + A · C · x + A · C · z + B · C · y + B · C · z + A · x + B · y + C · z
- Commutative law: a+b=b+a, a·b=b·a. Associative law: (a+b)+c=a+(b+c), (a·b)·c=a·(b ·C).
From the second step, it can be seen that there are pairs of sub-terms with common algebraicA · B · x
, such as: 0615583aae308b,A · x
; According to the commutative law and associative law, they can be combined. Here, take these two as examples:A · B · x + A · x
- law of zero (unitary law): a+0=a, a·1=a.
A · B · x + A · x · 1
- distribution law: a·(b+c)=(a·b)+(a·c), (a+b)·c=(a·c)+(b·c)
A · x · (B + 1)
- law of elementary elements (law of extreme elements): a+1=1, a·0=0.
A · x
According to the calculation of steps 3~6,
A · B · x + A · x = A · x
. Repeat the above steps to calculate the other pairwise subalgebras and finally get the algebraic formula:A · x + B · y + C · z
At this point, the Boolean algebraic formula can no longer be optimized, then it can be converted into the following code according to the original agreement:
(op.is_show_lock && !o.is_lock) || (op.is_show_sf && !o.is_sf) || (op.is_show_bz && !o.is_bz)
Write at the end
In my 5 years of development, I have not encountered the subject of the subject, and the probability of this kind of code should be relatively small. Even if they do, most people may use the other solutions in the answer, but most of them escape Without looping, the complexity is directly changed from O(1) to O(N). Although the final impact is minimal, it is harmless to understand other better solutions, and the readability is also improved. If the reader is You can try this technique when you encounter such code.
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。