[英]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 }
或在链接上查看演示
我有些犹豫,只是简单地用翻译后的代码块做出响应,而我继续学习的建议是,尝试用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.