JS point recursion with ramda

I am learning pointfree functions and trying to implement this recursive null remover in this style.

Works, but not pointfree:

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 

The following is my failed attempt:

 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 ) 
+5
source share
2 answers

Fortunately, JavaScript has the resources to deal with its lack of laziness. Thus, it is completely possible to declare a recursive solution from zero point using lambda functions as follows: a => f(a) . Just replace R.map(removeNull) with 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 ) 

In your case, I recommend using R.reject , which is an oposite for R.filter . Since you deny the predicate, R.filter(R.pipe(R.isNil, R.not)) is equal to 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 ) 

Finally, this function has the following ifElse(predicate, whenTrue, identity) structure, which is equal to 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)) ) ) 
+6
source

The lack of laziness Javascript is a double killer here: you cannot call it when its const, because you are in the same area and trying to resolve resolNulls in your definition.

Also, you cannot just match (recurseAction (action)), since the definition itself will delete the stack, so you need to wrap it in another area to do this:

 const {ifElse, always, tap, apply, either, is, isNil, not, pipe, filter, map, identity} = require('ramda') const filterNotNull = filter(pipe(isNil, not)) const log = tap(console.log) const recurseAction = action => ifElse( either(is(Array), is(Object)), pipe( action, map(a => recurseAction(action)(a)) ), identity ) const removeNulls = recurseAction(filterNotNull) const a = { a: null, b: "blah", c: 2, d: undefined, e: { meow: null, blah: undefined, jim: 'bob' } } const b = removeNulls(a) console.log(b) 
+2
source

Source: https://habr.com/ru/post/1260838/


All Articles