删除 if 语句



如果可以避免语句,则被认为是一种很好的做法。

例如,此代码:

if (a > 80) {
a = 80;
}

可以变成这样:

a = Math.min(80, a);

这样代码就被认为是更干净的,因为没有分支逻辑。

但是,对于像这样更复杂的问题,有什么方法可以避免:

if (array.length > 5) {
array = array.reverse().join('');
} else {
array = 'array is lte 5';
}

如果数组长度> 5,则反转并连接它,否则返回"数组是 lte 5"。

这是一个简单的例子,但比第一个例子更复杂,如果很难删除。

数学如何处理分支,是否有可能在数学中表达这种逻辑。

我可以将其提取到单独的方法中,但它只会移动方法本身中的 if 语句,不会删除它。

我可以想象我可以使用 Ramdajs 中的一些函数,但我没有找到合适的函数,即使我找到了一个 if 我会在那里,我想它只会被抽象化。

还可以想象这个 sudo 代码:

if (file_exists(file)) {
content = file_read(file);
if (content.startsWith('config')) {
ret = 'config:'; 
} else if (content.endsWith(':app')) {
ret = ':app';
}  
} else {  
ret = '';
}

这段代码只有 2 个 if 语句,但阅读和更改已经是一场噩梦。

是否可以使用数学和/或更清楚地表达它,避免分支。

我知道在数学中没有"读取文件",但这只是一个示例。

谢谢

一种方法是将您需要操作的东西放在一个"盒子"中,您可以在其上应用一系列操作(即函数(。这会强制您删除任何嵌套条件。

此伪代码:

if (file_exists(file)) {
content = file_read(file);
if (content.startsWith('config')) {
ret = 'config:'; 
} else if (content.endsWith(':app')) {
ret = ':app';
}  
} else {  
ret = '';
}

可以替换为:

const ret =
[file]
.map(x => file_exists(x) ? file_read(x) : '')
.map(x => x.startsWith('config') ? 'config:' : x)
.map(x => x.endsWith(':app') ? ':app' : x)
.pop();

请注意,以上我们可以使用函数组合进行转换:

const ret =
pipe(
ifElse(file_exists, file_read, always('')),
when(startsWith('config'), always('config:')),
when(endsWith(':app'), always(':app')))
(file)

当然,有人可能会争辩说你执行了不必要的检查,但除非发现了性能问题,否则我总是倾向于可读性而不是其他任何东西。

我们可以在这里提高可读性吗?我们当然可以尝试:

const ret =
[file]
.map(load_file_content)
.map(when_starts_with('config'))
.map(when_ends_with(':app'))
.pop();

const ret =
pipe(
load_file_content,
when_starts_with('config'),
when_ends_with(':app'))
(file)

我觉得这可读,但其他人可能不是这样 🤷 ♂️

除了三元运算符(可能不会使事情更清晰(之外,您是否考虑过早期回报?

if (!file_exists(file)) {
return '';
}
content = file_read(file);
if (content.startsWith('config')) {
return 'config:'; 
}
if (content.endsWith(':app')) {
return ':app';
}
return ...;

幕后仍然会有同样多的分支逻辑,但通过这种方式,您可以在逻辑上解开语义上不同的代码块。

最新更新