简体   繁体   中英

Ramda reject - is there a more elegant way to write this?

const people = [
  {
    name: 'bill',
    age: 52
  },
  {
    name: 'james',
    age: 27
  },
  {
    name: 'james',
    age: 17
  }
]

const newPeople = R.reject(person => {
  return R.includes('jam', person.name)
})(people)

Is there a more elegant Ramda way to write this? I am looking to return an array that removes all people objects that have the string jam in their name.

Perhaps something like R.reject(R.where(...)) ?

Thanks!

I think you were on the right track with where .

This reads quite well to me:

 const jamless = reject (where ({name: includes ('jam')})) const people = [{name: 'bill', age: 52}, {name: 'james', age: 27}, {name: 'james', age: 17}] console .log ( jamless (people) ) 
 <script src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.26.1/ramda.js"></script> <script> const {reject, where, includes} = R </script> 

Reading the keywords aloud, we can hear "reject where name includes 'jam'", not a bad English description of the problem.

If you want to parameterize this, it could just be

const disallow = (str) => reject (where ({name: includes(str)}) )
const jamless = disallow ('jam')

(Although I'm quite sure we could make a point-free version of disallow , I see no reason to try, as this is already quite readable.)

See also the related answer, https://stackoverflow.com/a/29256202

I would break this down into smaller functions:

withJam

Returns true if a string contains the string jam (case insensitive)

const withJam = R.test(/jam/i);
withJam('Bill') //=> false
withJam('James') //=> true

nameWithJam

Returns true if a property contains the string jam (case insensitive)

const nameWithJam = R.propSatisfies(withJam, 'name');
nameWithJam({name: 'Bill'}) //=> false
nameWithJam({name: 'James'}) //=> true

Then you can write:

R.reject(nameWithJam)(people)

I think that your initial solution is good enough already. I just made it pointfree, ie without mentioning the parameters explicitly.

Example:

Let's say that you need a function that adds 5 to any number:

const add5 = n => n + 5;
add5(37) //=> 42

You could get rid of n if you could work with a curried version of add . Let's define add first:

const add = m => n => m + n;

Then let's create add5 :

const add5 = add(5);
add5(37) //=> 42

You can replace this:

[1,2,3].map(n => n + 5) //=> [6,7,8]

With:

[1,2,3].map(add(5)) //=> [6,7,8]

⚠️ Pointfree style is certainly interesting and worth exploring. But it can also unnecessarily complicate things :) See When is it appropriate to choose point-free style vs a data-centric style in functional programming?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM