Reputation: 1464
Using Ramda Js, I need to create a function that can set one object property using the value of a different property on the same object. My attempt so far is as follows:
var foo = R.set(R.lensProp('bar'), 'foo' + R.prop('foo'));
var result = foo({foo:"bar"});
Desired result:
{foo:"bar", bar:"foobar"}
Actual result:
{foo:"bar", bar: "foofunction f1(a) {... etc"}
Clearly I'm misunderstanding something here, and any insights into how to approach this would be appreciated.
Upvotes: 5
Views: 14001
Reputation: 50807
I had just coded something like the answer from @davidchambers and then made a points-free version, only to show how much simpler the lambda actually is. Rather than throw it out, here's how bad it looks in comparison:
var foo = (obj) => R.assoc('bar', 'foo' + obj.foo, obj);
var foo = R.converge(R.assoc('bar'), [R.pipe(R.prop('foo'), R.concat('foo')), R.identity]);
These two, with an intermediate version are available on the Ramda REPL
Upvotes: 11
Reputation: 3866
I would slice the issue into 2 parts: first you need to copy the foo
property of an object to bar
, then change bar
's value. There is no out of the box solution in ramda for the 1st, but you can use evolve
for the second:
import { curry, assoc, compose, evolve } from 'ramda'
// String -> String -> {k: v}
const copyPropAs = curry((from, to, obj) => assoc(to, obj[from], obj))
// String -> String -> String
const prefix = curry((value, string) => value + string)
const fn = compose(
evolve({
foo: prefix('foo')
}),
copyPropAs('foo', 'bar')
)
fn({foo: 'bar'})
I know, that it's not all point free, but with this way the problematic part is isolated to a point where it can no longer be broken to smaller parts, and we can always come back to those to find better implementations.
Upvotes: 0
Reputation: 24856
Lenses are not a good fit when the value of one property depends on the value of another property. A lambda is probably best here:
const foo = o => R.assoc('bar', 'foo' + o.foo, o);
foo({foo: 'bar'});
// => {foo: 'bar', bar: 'foobar'}
Upvotes: 13