使用透镜将当前函数映射到数组上

问题描述 投票:1回答:1

我有一个对象,并希望使用其他对象对象来更新该对象内部数组中的每个值。这是我正在尝试的内容:

import * as R from 'ramda'

const obj = {
    array: [ 1, 2, 3 ],
    incrementBy: 0
};

const doIncrement = R.curry((inc,val) => {
    return val+inc;
});

const incrementLens = R.lensProp('incrementBy');
const setIncrementToOne = R.set(incrementLens,1);

const newObj = setIncrementToOne(obj);

const arrayLens = R.lensProp('array');

const incrementA = R.over(arrayLens, R.map(doIncrement(1)));

const incrementB = R.pipe(
    setIncrementToOne,
    R.chain(
        R.over(arrayLens, R.map(doIncrement)),
        R.view(incrementLens)
    )
)

console.log(JSON.stringify(incrementA(newObj))); // works: {"array":[2,3,4],"incrementBy":1}
console.log(JSON.stringify(incrementB(obj))); // does not work (TypeError: Cannot read property 'fantasy-land/map' of undefined)

版本A显然可以在我直接访问数组并在其上映射咖喱函数时起作用。但是,在版本B中,我不确定事物的顺序。我现在尝试过的操作似乎无法正确地将R.view中的值传递给curried函数。

(注意:用例更加复杂,我想了解如何同时使用咖喱函数,地图和镜头。)

javascript ramda.js lenses
1个回答
2
投票

[将R.chain应用于函数-chain(f, g)(x)等效于f(g(x))(x)-将函数g应用于值'x',返回,然后将函数f应用于g(x)的结果,然后值x

根据您的情况:

  • [g(x)R.view(incrementLens))为1
  • [fR.over(arrayLens, R.map(doIncrement)))是一个等待值的函数(不是另一个函数)

f上应用R.over...g(x))在非对象值上应用了镜头,即使它是一个对象,其结果也将是另一个值,这意味着您没有功能应用于管道中setIncrementToOne的结果。

在这种情况下,g(x)的结果需要是一个函数,R.over可以将其与arraylens一起使用-以获得与R.over(arrayLens, R.map(R.add(1)))相同的incrementA

注意:我已经用doIncrement替换了R.add,这具有相同的作用。

const obj = {
  array: [1, 2, 3],
  incrementBy: 0
};

const incrementLens = R.lensProp('incrementBy');
const setIncrementToOne = R.set(incrementLens, 1);
const newObj = setIncrementToOne(obj);
const arrayLens = R.lensProp('array');

const incrementB = R.pipe(
  setIncrementToOne,
  R.chain(
    R.over(arrayLens),
    R.pipe(R.view(incrementLens), R.add, R.map)
  )
)

const incrementA = R.over(arrayLens, R.map(R.add(1)));

console.log(JSON.stringify(incrementA(newObj))); // works: {"array":[2,3,4],"incrementBy":1}
console.log(JSON.stringify(incrementB(obj))); // works: {"array":[2,3,4],"incrementBy":1}
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.26.1/ramda.js"></script>
© www.soinside.com 2019 - 2024. All rights reserved.