将 Javascript if/else 翻译成 Ramda 条件问题

Translate Javascript if/else to Ramda cond issue

我在if/else逻辑检查后发现了一些处理上的问题。举个例子吧。

基本配置

const result = {
  data: 1,
  state: {
    pass: 'N'
  }
}

对于JS if/else检查,逻辑检查后日志应该不会显示

function checking() {
  if(result.state.pass !== 'Y') {
    return result;
  }

  console.log("Should not appear the log")
}

checking()

然后,我尝试使用 Ramda cond 函数翻译它

function checking() {
  R.cond([
    [
      R.compose(R.not, R.equals('Y'), R.prop('pass'), R.prop('state')),
      (res) => res
    ]
  ])(result)

  console.log("Should not appear the log")
}

checking()

但是,日志出现在 Ramda cond 示例中。我可以知道

谢谢。

您忘记添加 return 语句。

const result = {
  data: 1,
  state: {
    pass: 'N'
  }
}

function checking() {
  // Need to add return statement below
  return R.cond([
    [
      R.compose(
        R.not, 
        R.equals('Y'), 
        R.prop('pass'), 
        R.prop('state')),
      (res) => res
    ]
  ])(result)

  console.log("Should not appear the log")
}
  
checking() 
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.23.0/ramda.min.js"></script>

已更新:我最初是倒着看这篇日志应该在什么时候显示。


我的建议是这样的:

const checking = R.when(
  R.compose(R.equals('Y'), R.path(['state', 'pass'])),
  (res) => {console.log("Should not appear in the log"); return res;}
)

这是我从你的代码中得到的结果:我的第一步是修正 cond:

的使用
const result1 = {data: 1, state: {pass: 'N'}}
const result2 = {data: 2, state: {pass: 'Y'}}

const checking = R.cond([
  [
    R.compose(R.not, R.equals('Y'), R.prop('pass'), R.prop('state')),
    R.identity
  ],
  [
    R.T, 
    (res) => {console.log("Should not appear in the log"); return res;}
  ]
])

checking(result1); 
//=> {data: 1, state: {pass: 'N'}} 
checking(result2);
// logs "Should not appear in the log
//=> {data: 2, state: {pass: 'Y'}}

请注意,cond 最像一个 switch 语句:它接受条件结果对的集合,return 是一个函数,该函数将其参数传递给每个对,直到找到一个条件为真,那么它 return 是调用其结果的结果。因此对于第二个条件,我们只检查 R.T,这是一个总是 returns true 的函数,并使用 identity 到 return 输入。

这个新函数现在接受一个 result 对象,并且 return 保持不变,如果它与初始测试不匹配,则将消息记录到控制台。


但这还没有结束。此代码可以重构。

这是我要应用的一个简单修复方法:

const checking = R.cond([
  [
    R.compose(R.not, R.equals('Y'), R.path(['state', 'pass'])),
    R.identity
  ],
  [
    R.T, 
    (res) => {console.log("Should not appear in the log"); return res;}
  ]
])

这只是从 compose(prop('pass'), prop('state')) 更改为 path(['state', 'pass'])。这是一个小调整,但我认为这更干净。


下一个变化更具实质性。

const checking = R.ifElse(
  R.compose(R.not, R.equals('Y'), R.path(['state', 'pass'])),
  R.identity,
  (res) => {console.log("Should not appear in the log"); return res;}
)

当我们有一个只有两个分支的 cond 语句,而第二个在 R.T 上测试时,我们可以用 ifElse 写得更清楚。这需要一个条件和两个结果,一个用于条件通过,一个用于条件失败。


这可能是您想要达到的程度,特别是如果您最终计划在失败情况下做一些不同的事情。但如果你不是,而且你真的只需要一个结果,那么 R.unless 提供了对 ifElse 的进一步简化,对于那些第二个结果只是传递的情况:

const checking = R.unless(
  R.compose(R.not, R.equals('Y'), R.path(['state', 'pass'])),
  (res) => {console.log("Should not appear in the log"); return res;}
)

unless 只是检查条件并在条件为假时运行结果,如果条件为真 return 则输入完好无损。


但是我们也可以通过从 unless 切换到 when 来拉出 not:

const checking = R.when(
  R.compose(R.equals('Y'), R.path(['state', 'pass'])),
  (res) => {console.log("Should not appear in the log"); return res;}
)

我可能会把它留在那里,尽管为了清楚起见,我可能会分解出一个 log 函数。

所有这些都可以在 Ramda REPL.

上获得(包括具有 log 功能的最终版本)