Ramda拒绝-有没有更优雅的方式来编写此代码?

时间:2019-08-29 15:55:08

标签: javascript functional-programming ramda.js

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)

有没有更优雅的 Ramda 方式来编写此代码?我希望返回一个数组,该数组删除名称中包含字符串jam的所有人物对象。

也许像R.reject(R.where(...))之类的东西?

谢谢!

2 个答案:

答案 0 :(得分:4)

我认为您在where方面步入正轨。

这对我来说很好听:

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>

大声阅读关键字,我们会听到“拒绝名称包含'jam'的声音”,这不是问题的英文说明。

如果要对此进行参数化,则可能只是

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

(尽管我非常确定我们可以制作disallow的无点版本,但我认为没有理由尝试,因为它已经很容易理解了。)

另请参阅相关答案https://stackoverflow.com/a/29256202

答案 1 :(得分:1)

我将其分解为较小的功能:

withJam

如果字符串包含字符串true(不区分大小写),则返回jam

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

nameWithJam

如果属性包含字符串true(不区分大小写),则返回jam

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

然后您可以编写:

R.reject(nameWithJam)(people)

我认为您的初始解决方案已经足够好了。我只是使它毫无意义,即没有明确提及参数。

示例:

假设您需要一个将5添加到任意数字的函数:

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

如果可以使用n的最新版本,则可以摆脱add。首先定义add

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

然后创建add5

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

您可以替换为:

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

使用:

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

⚠️Pointfree风格肯定很有趣,值得探讨。但这也可能不必要地使事情复杂化:)参见When is it appropriate to choose point-free style vs a data-centric style in functional programming?