简体   繁体   English

我如何在此代码中使用ramda.js?

[英]How can i use ramda.js with this code?

I am beginning to use ramda, but have doubts about how to implement functions ramda. 我开始使用ramda,但对如何实现ramda函数有疑问。

This code is to mount a select object to do queries for sequelize. 这段代码是安装一个选择对象来进行序列化查询。

See code: 看到代码:

const stringRequired = string => !!string.length
const numberRequired = number => Number.isInteger(number)

const validadeInput = (value, initial, validade) => (
  validade(value) ? value : initial
)

const input = (obj, key, initial, validade) => (
  typeof obj[key] !== 'undefined' ?
  validadeInput(obj[key], initial, validade) :
  initial
);

const addValue = (obj, key, value) => {
  const prop = {}
  prop[key] = value
  return Object.assign(obj, prop)
}

const addFilter = (obj, key, value, validate) => (
  validate(value) ? addValue(obj, key, value)
  : obj
)

const selector = (query = {}) => {
  const limit = input(query, 'limit', 10, numberRequired);
  const name = input(query, 'name', '', stringRequired);

  let select = {}

  select = addFilter(select, 'name', name, stringRequired);
  select = addFilter(select, 'limit', limit, numberRequired);

  return select
}

console.log(selector()); 
// { limit: 10 }
console.log(selector({ name: 'David Costa' })); 
// { limit: 10, name: 'David Costa' }
console.log(selector({ limit: 50 }));
// { limit: 50 }

Or see demo on link 或在链接上查看演示

http://jsbin.com/zerahay/edit?js,console,output http://jsbin.com/zerahay/edit?js,控制台,输出

I'm a little hesitant to simply respond with a translated block of code and my recommendation for learning going forward would be to try replace the functions you already have one by one with those from Ramda. 我有些犹豫,只是简单地用翻译后的代码块做出响应,而我继续学习的建议是,尝试用Ramda的功能逐一替换您已经拥有的功能。

Hesitation aside, the following offers one example of what your code might look like when using various functions from Ramda. 除了犹豫,下面提供了一个示例,说明使用Ramda的各种功能时代码的外观。

 // The existing check for `!!string.length` allows for potential issues with // arrays being passed in and incorrectly validating, so this will ensure the // value is indeed a string before checking its length const stringRequired = R.both(R.is(String), R.complement(R.isEmpty)) // `addFilter` produces a function that takes an object and uses the provided // function to validate the value associated with the provided key if it exists // otherwise using the provided `initial` value. If valid, an object containing // the key and value will be returned, otherwise an empty object is returned. const addFilter = (validate, initial, key) => R.pipe( R.propOr(initial, key), R.ifElse(validate, R.objOf(key), R.always({})) ) // `selector` takes an object and passes it to each function generated by // calling `addFilter`, merging the resulting objects together. const selector = (q = {}) => R.converge(R.merge, [ addFilter(stringRequired, '', 'name'), addFilter(Number.isInteger, 10, 'limit') ])(q) console.log(selector()) console.log(selector({ name: 'David Costa' })) console.log(selector({ limit: 50 })) 
 <script src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.25.0/ramda.min.js"></script> 

Why? 为什么?

I think you need to consider why you want to convert this to Ramda (Disclaimer: I'm a Ramda author) Ramda is a library, a toolkit. 我认为您需要考虑为什么要将其转换为Ramda(免责声明:我是Ramda的作者)Ramda是一个库,一个工具包。 Use it when it helps clean up your code or when it makes it easier to understand the problem and its solution. 当它有助于清理代码或使它易于理解问题及其解决方案时,请使用它。 Don't use it when it doesn't. 不使用时请勿使用。

That said, I did refactor it, using Ramda: 也就是说,我确实使用Ramda对其进行了重构:

A Refactoring 重构

I simply tried to refactor it a bit. 我只是尝试重构一下。 In the end, I replaced all your helper functions with a single one that takes a list of conditions such as ['limit', 10, numberRequired] to create a function equivalent to your selector . 最后,我用一个带有一系列条件(例如['limit', 10, numberRequired]的单个替换了您的所有辅助函数,以创建一个与selector等效的函数。

I did use a few Ramda functions along the way, but the only one that offers substantive help is assoc , which creates a new object from an old one and a key and value. 在此过程中,我确实使用了一些Ramda函数,但是唯一提供实质性帮助的函数是assoc ,它从一个旧对象以及一个键和值创建了一个新对象。 Using, for instance, compose(Boolean, length) is cleaner than const stringRequired = string => !!string.length , but it's not a large difference. 例如,使用compose(Boolean, length)const stringRequired = string => !!string.length干净,但差别不大。

The important change, to my mind, is the makeSelector function, which makes creating your selector function much more declarative. 在我看来,重要的变化是makeSelector函数,它使创建selector函数更具声明性。 It's a bit ugly, and I probably would write it differently if I were starting from scratch, but I did this in a series of steps, inlining your helper functions until I had a reasonably short function that had the same behavior. 这有点丑陋,如果我是从头开始的话,我可能会写不同的方式,但是我通过一系列步骤做到了这一点,内联您的辅助函数,直到我拥有一个具有相同行为的合理的短函数。

 // rules const stringRequired = R.compose(Boolean, R.length) const numberRequired = number => Number.isInteger(number) // utils const makeSelector = (conditions) => (query = {}) => R.reduce( (select, [key, initial, validate]) => { const value = key in select && validate(select[key]) ? select[key] : initial; return validate(value) ? R.assoc(key, value, select) : select }, query, conditions ) // main const selector = makeSelector([ ['limit', 10, numberRequired], ['name', '', stringRequired] ]) console.log(selector()); console.log(selector({ name: 'David Costa' })); console.log(selector({ limit: 50 })); 
 <script src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.25.0/ramda.js"></script> 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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