在对象上执行函数,然后在Ramda中对对象进行操作。

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

我在纠结一点公羊达的逻辑,我觉得我已经差不多掌握了,但我的大脑今天就是不正常工作。

我有一个对象,我想提取 "name "和 "value"。

const thing = {
  'name': 'thing',
  'value': 1000.0987654321,
  'valueAsString': "1000.0987654321",
  'otherThings': { 'blah': 'blah' },
}

我想从事物中提取 "名称 "和 "值", 但我想在返回新对象之前把值取整.

我知道要提取name和value,我可以使用pick。R.pick(['name', 'value']) 而要执行我的四舍五入函数,我可以使用一个现有的四舍五入函数,

const roundTo9Dp = (n) => Number((n).toFixed(9))

然后像这样应用到我的对象上。R.compose(roundTo9Dp, R.prop('value'))

这两个操作是独立工作的

const picker = R.pick(['name', 'value'])
picker(thing) // => {"name": "thing", "value": 1000.0987654321}

const rounded = R.compose(roundTo9Dp, R.prop('value'))
rounded(thing) // => 1000.098765432

当我把它们结合在一起的时候,我就会感到困难。就好像它们在不同的层次上对'物'进行操作,而我只是在努力地解开它们。

R.compose(picker, R.assoc('value', rounded))(thing) // Incorrect
picker(R.compose(R.assoc('value'), rounded)(thing)(thing)) // works, but is hideous
javascript functional-programming ramda.js
1个回答
6
投票

用Ramda有很多方法可以做到这一点。 这里有几种。

const roundTo9Dp = (n) => Number((n).toFixed(9))

const foo1 = applySpec({
  name: prop('name'),
  value: compose(roundTo9Dp, prop('value'))
})

const foo2 = pipe(
  pick (['name', 'value']),
  over (lensProp ('value'), roundTo9Dp)
)

const rounded = R.compose(roundTo9Dp, R.prop('value'))
const foo3 = pipe(
  pick (['name', 'value']),
  chain(assoc('value'), rounded)
)

const foo4 = pipe(
  props (['name', 'value']),
  zipWith (call, [identity, roundTo9Dp]),
  zipObj (['name', 'value'])
)

const thing = {name: 'thing', value: 1000.0987654321, valueAsString: "1000.0987654321", otherThings: {blah: 'blah'}}

console .log ('foo1:', foo1 (thing))
console .log ('foo2:', foo2 (thing))
console .log ('foo3:', foo3 (thing))
console .log ('foo4:', foo4 (thing))
<script src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.27.0/ramda.js"></script>
<script> const {applySpec, prop, compose, pipe, pick, over, lensProp, chain, assoc, props, zipWith, call, identity, zipObj} = R </script>

如果我们尝试的话还可以想出更多的办法 foo3 可能是最接近你所苦恼的。 chain 当应用于函数时,它的工作原理是 chain (f, g) (x) //=> f (g (x)) (x),这将避免丑陋的 (thing) (thing) 在你的版本中。 这个版本可能会让你了解一些关于 梦幻乐园 类型类。 foo1 使用Ramda比较方便的一个对象操作函数。applySpec. foo2 用途 lensPropover,它可以带领你进入迷人的镜头世界。 而 foo4虽说可能不推荐,但却展示了 zipWithzipObj,用于组合列表的函数。

但除非这是关于 学习 Ramda,我建议这些都不要用,因为这很简单,在现代JS中不需要任何库就可以做到。

const foo = ({name, value}) => 
  ({name, value: roundTo9Dp(value)})

我是Ramda的创始人之一,而且我还是它的忠实粉丝。 但我认为它是一个库,当它能让代码更干净、更可维护时,就可以使用。 这里,最简单的版本不需要它。

© www.soinside.com 2019 - 2024. All rights reserved.