使用Ramda Js,我需要创建一个函数,该函数可以使用同一对象上不同属性的值设置一个对象属性。我到目前为止的尝试如下:
var foo = R.set(R.lensProp('bar'), 'foo' + R.prop('foo'));
var result = foo({foo:"bar"});
期望的结果:
{foo:"bar", bar:"foobar"}
实际结果:
{foo:"bar", bar: "foofunction f1(a) {... etc"}
显然,我在这里误解了一些内容,并且对如何处理此问题的任何见解都将不胜感激。
答案 0 :(得分:10)
当一个属性的值取决于另一个属性的值时,镜头不适合。 lambda可能是最好的:
const foo = o => R.assoc('bar', 'foo' + o.foo, o);
foo({foo: 'bar'});
// => {foo: 'bar', bar: 'foobar'}
答案 1 :(得分:7)
我刚刚编写了类似@davidchambers的答案,然后制作了一个无点版本,只是为了表明lambda实际上有多简单。而不是把它扔出去,这里看起来有多糟糕:
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]);
提供这两个中间版本
答案 2 :(得分:0)
我将问题分成两部分:首先,您需要将对象的foo
属性复制到bar
,然后更改bar
的值。 ramda的第一个方法没有开箱即用的解决方案,但是第二个可以使用evolve
:
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'})
我知道,并不是所有的点都是免费的,但是通过这种方式,有问题的部分被隔离到无法再分解成较小的部分的程度,我们总是可以回到那里找到更好的实现。 / p>