4

使用 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"}

显然我在这里误解了一些东西,任何关于如何解决这个问题的见解都将不胜感激。

4

3 回答 3

12

当一个财产的价值取决于另一财产的价值时,镜头就不适合了。lambda 在这里可能是最好的:

const foo = o => R.assoc('bar', 'foo' + o.foo, o);

foo({foo: 'bar'});
// => {foo: 'bar', bar: 'foobar'}
于 2016-01-07T19:54:31.977 回答
11

我刚刚编写了类似于@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]);

Ramda REPL上提供了这两个中间版本

于 2016-01-07T20:10:07.443 回答
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'})

我知道,这并不是完全没有问题的,但是通过这种方式,有问题的部分被隔离到不能再分解成更小的部分的程度,我们总是可以回到那些地方找到更好的实现。

于 2019-04-29T13:06:44.560 回答