将 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
功能的最终版本)
我在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
功能的最终版本)