链式逻辑运算符分配到函数式编程

Posted

技术标签:

【中文标题】链式逻辑运算符分配到函数式编程【英文标题】:Chained logical operator on asigment to functional programming 【发布时间】:2022-01-14 06:28:24 【问题描述】:

我正在尝试处理几个选项来以最干净的方式填充变量内容。

最简单的情况是:

const value = foo.bar || 'Default';

当我想添加条件时,我通常喜欢:

const value = foo.bar || (n > 10 ? n : 'Default');

可以重构为:

const value = foo.bar || (n > 10 && n) || 'Default';

我的疑问是当有几个阶段时,是否可以通过这种方式复制或使用经典条件来解决

选项 A(逻辑运算符)

const value = foo.bar
  || (n > 10 && n)
  || (n > 0 && 0)
  || 'Default';

选项 B(带三元条件)

const value = foo.bar
  || (n > 10 && n)
  || (n > 0 ? 0 : 'Default');

选项 C(经典条件)

let value;
if(foo.bar) 
  value = foo.bar;
 else if(n > 10) 
  value = n;
 else if(n > 0) 
  value = 0;
 else 
  value = 'Default';

【问题讨论】:

您是否尝试过复制它并查​​看它的反应? 你忘了开关/机箱,顺便问一下问题是什么?) 问题是什么是最干净的方式,如果我选择的选项 A 是否是干净代码的好习惯。 我不会说 any 这些是“最干净”的方式。 Maybe/Optional 或可能是 Either 将是使用 FP 处理此问题的更好方法。甚至可能是cond from Ramda。所有链式复杂操作都难以维护和推理。 这样做的目的是避免使用let,选项C是什么,具有可读的解决方案并且不使用第三个库。 Switch/case 不是一个选项,因为它不适用于复杂的条件。 【参考方案1】:

不要滥用逻辑 &&|| 运算符作为条件。 (n > 0 && 0) || 'Default' 不符合您的预期,由于 0 的虚假性,它总是评估为 'Default'

只剩下三元条件运算符

const value = foo.bar
  ? foo.bar
  : n > 10
    ? n
    : n > 0
      ? 0
      : 'Default';

或等效的条件语句

let value;
if (foo.bar) 
  value = foo.bar;
 else if (n > 10) 
  value = n;
 else if (n > 0) 
  value = 0;
 else 
  value = 'Default';

foo.bar || …确实在这里工作,但我会避免在这种特殊情况下保持视觉一致性)。


为了完整起见,另一种选择是 IIFE;这样您仍然可以使用表达式初始化常量,但无需嵌套条件运算符:

const value = (() => 
  if (foo.bar) return foo.bar;
  if (n > 10) return n;
  if (n > 0) return 0;
  return 'Default';
)();

【讨论】:

这个想法是从我配置的 ESlint 开始的,它验证了嵌套三元条件的使用是错误的。这就是为什么我没有考虑将您的第一反应作为一种选择。我认为 IIFE 是一个不错的选择。 @GabrielRodríguezFlores Tbh 我只会禁用该 eslint 规则。有了适当的缩进,嵌套条件运算符就没有什么令人困惑或不清楚的地方了。 我同意你的观点,我正在使用 eslint 推荐和 airbnb 样式,这是预设规则之一。我只是想知道哪种方式更清洁。

以上是关于链式逻辑运算符分配到函数式编程的主要内容,如果未能解决你的问题,请参考以下文章

(电工电子)一题一练:根据逻辑函数式画逻辑图

JS基础(JavaScript三大特点基本数据类型检测逻辑运算符的短路运算几大循环结构的特点)

C++ 运算符重载三(链式编程)

通过逻辑运算符 OR 分配默认值

java自制简易函数式编程库初出炉

函数式编程-只用"表达式",不用"语句"()