繁体   English   中英

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

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

我开始使用ramda,但对如何实现ramda函数有疑问。

这段代码是安装一个选择对象来进行序列化查询。

看到代码:

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 }

或在链接上查看演示

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

我有些犹豫,只是简单地用翻译后的代码块做出响应,而我继续学习的建议是,尝试用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> 

为什么?

我认为您需要考虑为什么要将其转换为Ramda(免责声明:我是Ramda的作者)Ramda是一个库,一个工具包。 当它有助于清理代码或使它易于理解问题及其解决方案时,请使用它。 不使用时请勿使用。

也就是说,我确实使用Ramda对其进行了重构:

重构

我只是尝试重构一下。 最后,我用一个带有一系列条件(例如['limit', 10, numberRequired]的单个替换了您的所有辅助函数,以创建一个与selector等效的函数。

在此过程中,我确实使用了一些Ramda函数,但是唯一提供实质性帮助的函数是assoc ,它从一个旧对象以及一个键和值创建了一个新对象。 例如,使用compose(Boolean, length)const stringRequired = string => !!string.length干净,但差别不大。

在我看来,重要的变化是makeSelector函数,它使创建selector函数更具声明性。 这有点丑陋,如果我是从头开始的话,我可能会写不同的方式,但是我通过一系列步骤做到了这一点,内联您的辅助函数,直到我拥有一个具有相同行为的合理的短函数。

 // 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