使用ramda在JS中进行Pointfree递归

Hen*_*all 8 javascript recursion functional-programming pointfree ramda.js

我正在学习无点函数,并试图以该样式实现这个递归的空删除器.

工作,但不是免费的:

function removeNulls(obj) {
  return R.ifElse(
    R.either(R.is(Array), R.is(Object)),
    R.pipe(
      R.filter(R.pipe(R.isNil, R.not)),
      R.map(removeNulls)
    ),
    R.identity
  )(obj)
}

module.exports = removeNulls
Run Code Online (Sandbox Code Playgroud)

以下是我对此无效的尝试:

const removeNulls = R.ifElse(
  R.either(R.is(Array), R.is(Object)),
  R.pipe(
    R.filter(R.pipe(R.isNil, R.not)),
    // throws `ReferenceError: removeNulls is not defined`
    R.map(removeNulls)
  ),
  R.identity
)
Run Code Online (Sandbox Code Playgroud)

yos*_*bel 15

幸运的是,JavaScript有资源来处理它缺乏懒惰.因此,完全可以通过以下方式使用lambda函数来声明递归无点解决方案:a => f(a).只需更换R.map(removeNull)用R.map(a => removeNull(a)).

const removeNulls = R.ifElse(
    R.either(R.is(Array), R.is(Object)),
    R.pipe(
        R.filter(R.pipe(R.isNil, R.not)),
        R.map(a => removeNulls(a))
    ),
    R.identity
)
Run Code Online (Sandbox Code Playgroud)

在你的情况下,我会建议你使用R.reject哪个是对面的R.filter.既然你是在否定谓词,那就R.filter(R.pipe(R.isNil, R.not))等于R.reject(R.isNil)

const removeNulls = R.ifElse(
    R.either(R.is(Array), R.is(Object)),
    R.pipe(
        R.reject(R.isNil),
        R.map(a => removeNulls(a))
    ),
    R.identity
)
Run Code Online (Sandbox Code Playgroud)

最后,该函数具有以下结构ifElse(predicate, whenTrue, identity),它等于when(predicate, whenTrue)

const removeNulls = R.when(
    R.either(R.is(Array), R.is(Object)),
    R.pipe(
        R.reject(R.isNil),
        R.map(a => removeNulls(a))
    )
)
Run Code Online (Sandbox Code Playgroud)

简化版,关于Declan Whelan的评论,因为数组是Object

const removeNulls = R.when(
    R.is(Object),
    R.pipe(
        R.reject(R.isNil),
        R.map(a => removeNulls(a))
    )
)
Run Code Online (Sandbox Code Playgroud)

  • 为什么这个标记不被接受了.很好的答案 (3认同)