如何使用 R.zipWith 的预定义函数

How to use a predefined function with R.zipWith

这是初始数据集。

const Main = { 
  ratio : [ 0.5, 1, 2 ],
  focusPoint : [ 0.1, 0.2, 0.3 ],
}

我想用预定义的函数计算这个对象。

const width =  window.innerWidth
const height = window.innerHeight 
const ratioViewport = width / height
const resultY =  ( x, y )  =>   0.5 * ( x / ratioViewport ) - y 

这是最后一部分 R.zipWith 来计算函数。

const getPositionMain = applySpec ( {
   ratio : R.prop ('ratio'),
   resultY : R.zipWith ( resultY,  R.prop ('ratio') ,  R.prop ('focusPoint') ),
   } )
const positionMain = getPositionMain ( Main )

console.log( 'positionMain : ', positionMain )

// 期望输出 (positionMain) : [ 0.5 * (1 / ratioViewport) - 0.1, 0.5 * (2 / ratioViewport) - 0.2, 0.5 * (3 / ratioViewport) - 0.3 ]

但是,我没弄对。 我在这里做错了什么?

REPL

我不太清楚你想要什么。您在找这样的东西吗?

const getPositionMain = (w, ratioViewport = w.innerWidth / w.innerHeight) => main =>
  zipWith ((x, y) => 0.5 * (x / ratioViewport) - y) (main .ratio, main .focusPoint)


const _window = {innerWidth: 600, innerHeight: 400}
const Main = { 
  ratio : [ 0.5, 1, 2 ],
  focusPoint : [ 0.1, 0.2, 0.3 ],
}

console .log (getPositionMain (_window) (Main))
<script src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.27.1/ramda.js"></script>
<script> const {zipWith} = R                                         </script>

或者更像这样的东西?:

const getPositionMain = (w, ratioViewport = w.innerWidth / w.innerHeight) => (main) => ({
  ratio: main .ratio,
  resultY: zipWith ((x, y) => 0.5 * (x / ratioViewport) - y) (main .ratio, main .focusPoint)
})

const _window = {innerWidth: 600, innerHeight: 400}
const Main = { 
  ratio : [ 0.5, 1, 2 ],
  focusPoint : [ 0.1, 0.2, 0.3 ],
}

console .log (getPositionMain (_window) (Main))
<script src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.27.1/ramda.js"></script>
<script> const {zipWith} = R                                         </script>

无论哪种情况,代码都大同小异,只是输出结果的格式不同。

我可以获得的最接近您尝试的工作版本如下所示:

const getPositionMain = (w, ratioViewport = w.innerWidth / w.innerHeight) => applySpec ({
  ratio : prop ('ratio'),
  resultY : lift (zipWith ((x, y) => 0.5 * (x / ratioViewport) - y)) 
                 (prop ('ratio') ,  prop ('focusPoint'))
})

注意 zipWith 有一个函数和两个列表。您向它传递了初始函数和两个在正确调用时将解析为列表的函数。可以将解析为特定类型的函数视为这些类型的容器lift 采用一个对值进行操作的函数并将其提升为一个对这些值的容器进行操作的函数。所以lift (resultY) (f, g)大约是main => resultY (f (main), g (main)),然后我们可以在applySpec.

中使用它

在这里的每个版本中,我都避免使用 ratioViewport 的全局变量,从 Window 对象作为参数计算它。我觉得这更干净,但是 YMMV。

但是我们可以通过在 main 函数中执行廉价的视口计算来完全跳过该变量,如下所示:

const getPositionMain = ({innerWidth, innerHeight}) => ({ratio, focusPoint}) =>
  zipWith ((x, y) => 0.5 * (x / innerWidth * innerHeight) - y, ratio, focusPoint)

或者像这样:

const getPositionMain = ({innerWidth, innerHeight}) => ({ratio, focusPoint}) => ({
  ratio,
  resultY: zipWith ((x, y) => 0.5 * (x / innerWidth * innerHeight) - y, ratio, focusPoint)
})

这些是我喜欢的版本。