前段时间我用SVG编写了一个教育JavaScript应用程序(公司的封闭源代码)。在最基本的形式,应用程序由两列(左和右)组成,每列包含各种几何形状(正方形,三角形,圆形等)
一列中的每个几何形状都可以连接(通过绘制线)到相对列中的另一个几何形状。但是,任一列中的形状都可以与其建立一个或多个连接,具体取决于其设置。
因此设置为{multiple: false}
的形状只能有一个连接或来自它。连接是源自它还是源自另一种形状并不重要;一个连接只意味着一个连接,无论其来源如何。
通过绘制线来连接形状的代码部分是一个过于复杂的if语句。这是:
if ((!sourceHasLines && !targetHasLines) ||
(sourceHasLines && sourceCanMultiply && !targetHasLines) ||
(sourceHasLines && sourceCanMultiply && targetHasLines && targetCanMultiply) ||
(!sourceHasLines && !sourceCanMultiply && targetHasLines && targetCanMultiply) ||
(!sourceHasLines && sourceCanMultiply && targetHasLines && targetCanMultiply)) {
// Create a line only if one of the above comparisons succeeds
connection = self.connect($source, $target);
}
现在看一下代码,我觉得if语句中的逻辑可能会被压缩,我已经有了一些想法。但是,我觉得这与排列或其他CS相关逻辑(如离散数学)有关。我大多是自学成才的,所以我想看看有人会如何处理这个并重构上述if语句。
请注意,代码效果很好,但我想知道如何改进它。以下是原型的屏幕截图,其中包含顶行/底行而不是左/右列:
答案 0 :(得分:1)
怎么样:
if ((!SL || SM) && (!TL || TM)) ...
即:源必须为空或采用多行,目标必须为空或采用多行
答案 1 :(得分:1)
看看这两行
(!sourceHasLines && !sourceCanMultiply && targetHasLines && targetCanMultiply)
(!sourceHasLines && sourceCanMultiply && targetHasLines && targetCanMultiply)
如果其中任何一个为真,我们将画一条线
让我们来看看
a = source has lines
A = source can multiply
b = target has lines
B = target can multiply
以上两行成为
(1) ~a AND ~ A AND b AND B
(2) ~a AND A AND b AND B
我们正在使用(1)AND(2)进行决策,这使得当源没有线时A(源可以相乘)DONT CARE。
因此这两行可以替换为
(!sourceHasLines && targetHasLines && targetCanMultiply)
现在您的代码变为
if ((!sourceHasLines && !targetHasLines)
|| (sourceHasLines && sourceCanMultiply && !targetHasLines)
|| (sourceHasLines && sourceCanMultiply && targetHasLines && targetCanMultiply)
|| (!sourceHasLines && targetHasLines && targetCanMultiply)) {
connection = self.connect($source, $target);
}
可以进一步简化为
if ((!sourceHasLines || sourceCanMultiply) && (!targetHasLines || targetCanMultiply )) {
connection = self.connect($source, $target);
}
答案 2 :(得分:1)
您可以应用代数来减少代码的逻辑:
假设:
A = sourceHasLines;
B = targetHasLines;
C = sourceCanMultiply;
D = targetCanMultiply;
它将翻译成:
if ((!A && !B) ||
(A && C && !B) ||
(A && C && B && D) ||
(!A && !C && B && D) ||
(!A && C && B && D)) {
// Create a line only if one of the above comparisons succeeds
connection = self.connect($source, $target);
}
将使用代数转换:
(!A * !B) + ( A * C * !B ) + ( A * C * B * D) + ( !A * !C * B * D ) + ( !A * C * B * D )
应用一些数学:
!A * ( !B + ( B * D ) ) + A * C * ( !B + ( B * D ) )
( !B + ( B * D ) ) * ( !A + ( A * C ) )
(!A + C) * ( !B + D)
因此:
if(!sourceHasLines || sourceCanMultiply) && ( !targetHasLines || targetCanMultiply)) {
connection = self.connect($source, $target);
}