0

I like the implementation to be as generic and functional (as in functional programming) as possible, but generally speaking, i'm expecting a json objected with the following structure:

[
 {
   id: number,
   prop1: string,
   prop2: number,
   prop3: string,
   ...,
   propN: string
 },
 ...
]

(basically, an array of object that contain N properties, some mapped to strings and others to numbers)

I am trying to implement a generic set of functions so that i'll be able to achieve something to this end:

var filteredResult = filter(by(property, value, lt\gt\eq\contains), collection);

basically, I'd like to return an array with the same object structure, filtered by a property string that I pass into by(), along with the value (either a string or a number) and the type of comparison i'd like to perform.

generally speaking, for numbers I'd like to be able to filter results where property values are greater/lessthan/in range of the value I pass, with with strings, or arrays of strings, I'd like to find out if the property value contains the value I pass into by().

Since I'm new to FP, i'm struggling with formatting my code to take advantage of the auto-currying Ramda provides and I'm having trouble composing the different functions while passing the arguments I want.

For example, I've written this function:

var byProperty = function(p) {return R.useWith(R.filter, R.propEq(p), R.identity)};

but when I try to use it like so:

var property = 'prop1', value = 15;
console.log( byProperty( property, value, collection ) );

I get a function instead of the filtered array.

I know I'm missing something trivial here, but it's been kind of hard for me to wrap my head around the way values and functions are passed around in Ramda.

airbag
  • 75
  • 6

1 Answers1

1

but when I try to use it like console.log( byProperty( property, value, collection ) ) I get a function instead of the filtered array.

Yes, because your function takes only a single parameter, and returns a function. You could invoke it like this:

console.log( byProperty(property)(value, collection) );

but that's probably not what you want. Also, I think useWith is the wrong tool here, you just want a compose:

var byProperty = R.compose(R.filter, R.propEq);

though that still would need to be called like

console.log( byProperty(property, value)(collection) );

There is an open issue for this, but currying and composing variadic functions is not trivial. The best you'll get is probably

var byProperty = R.curryN(3, function(p, v, c) { return R.filter(R.propEq(p, v), c); });
Bergi
  • 630,263
  • 148
  • 957
  • 1,375
  • Thank you! This clears up a bunch of stuff for me. In your last example, would it be possible to pass a function reference as an argument, instead of the hard-coded R.propEq? – airbag Apr 14 '15 at 08:56
  • @airbag: Yes, you could. Just make sure `filter` gets called with what it expects - a predicate. – Bergi Apr 14 '15 at 15:10