我是ramdajs的新手。 假设我有一个对象:
{a: 1, b: 2, c: 3}
我可以这样做将a更改为11:
const aLens = R.lensProp('a');
R.set(aLens, 11, {a: 1, b: 2, c: 3});
如何通过一次通话将a更改为11,将b更改为22?
答案 0 :(得分:3)
如果您只需要使用已知值更新密钥,则可以选择使用R.merge
:
const obj = {a: 1, b: 2, c: 3}
R.merge(obj, {a: 11, b: 22}) //=> {"a": 11, "b": 22, "c": 3}
如果您需要根据现有值更新对象,则可以使用R.evolve
代替。
const abAdder = R.evolve({
a: add(10),
b: add(20)
})
abAdder(obj) //=> {"a": 11, "b": 22, "c": 3}
您也可以将其创建为镜头,但除非您计划将其与其他镜头合成,否则上述选项的好处是值得怀疑的。
const projectLens = keys => R.lens(R.pick(R.keys), R.flip(R.merge))
const abLens = projectLens(['a', 'b']);
R.set(abLens, { a: 11, b: 22 }, obj) //=> {"a": 11, "b": 22, "c": 3}
R.view(abLens, obj) //=> {"a": 1, "b": 2}
答案 1 :(得分:2)
嗯,你不能用镜头做到这一点。镜头专注于数据结构的单个部分。
Ramda' evolve
可能 do the trick :
JScrollPane
但我认为你需要在一次通话中考虑你的意思"。 Ramda提供compose
和pipe
(以及一些更加模糊的替代方案),允许您从多个调用中构建单个函数。如果你打电话给结果函数,你仍然只打一个电话,但是从一个非常真实的意义上说,你要调用管道中包含的所有函数。
因此,
const foo = {a: 1, b: 2, c: 3};
evolve({a: always(11), b: always(22)})(foo)// => {a: 11, b: 22, c: 3}
然而 a "single call" 到const fn = pipe(
set(lensProp('a'), 11),
set(lensProp('b'), 22)
);
fn({a: 1, b: 2, c: 3}); //=> {a: 11, b: 22, c: 3}
。
答案 2 :(得分:0)
实际上有一种方法可以用镜头做到这一点,但在这样的位置使用镜头可能不是最好的选择。
逻辑R.set
返回整个对象。所以它可以重复几次(链接)来执行你需要的任务:
const aLens = R.lensProp('a');
const bLens = R.lensProp('b');
R.set(bLens, 22)(R.set(aLens, 11)({a: 1, b: 2, c: 3}));
或更好的可视化:
const aLens = R.lensProp('a');
const bLens = R.lensProp('b');
R.compose(R.set(bLens, 22), R.set(aLens,11))({a: 1, b: 2, c: 3});
答案 3 :(得分:0)
你可以通过合并和咖喱来做到这一点:
curry(merge(__, {a:11, b:22}))({a:1, b:2, c:3});
我更喜欢使用这个util函数:
const overwrite = R.curry((over, org) => R.merge(R.__, over)(org));
overwrite({a:11, b:22}, {a:1, b:2, c:3});
答案 4 :(得分:0)
来自食谱的官方祝福方法: https://github.com/ramda/ramda/wiki/Cookbook#assocpaths
const obj = {a: 1, b: 2, c: 3};
const assocPaths = R.pipe(R.zipWith(R.assocPath), R.flip(R.reduce(R.applyTo)));
assocPaths(["a", "b"], [11, 22])(obj) //=> {"a": 11, "b": 22, "c": 3}