简体   繁体   中英

How can i use ramda.js with this code?

I am beginning to use ramda, but have doubts about how to implement functions 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

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.

Hesitation aside, the following offers one example of what your code might look like when using various functions from 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. 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:

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 .

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. Using, for instance, compose(Boolean, length) is cleaner than const stringRequired = string => !!string.length , but it's not a large difference.

The important change, to my mind, is the makeSelector function, which makes creating your selector function much more declarative. 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> 

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