我在纠结一点公羊达的逻辑,我觉得我已经差不多掌握了,但我的大脑今天就是不正常工作。
我有一个对象,我想提取 "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
用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
用途 lensProp
和 over
,它可以带领你进入迷人的镜头世界。 而 foo4
虽说可能不推荐,但却展示了 zipWith
和 zipObj
,用于组合列表的函数。
但除非这是关于 学习 Ramda,我建议这些都不要用,因为这很简单,在现代JS中不需要任何库就可以做到。
const foo = ({name, value}) =>
({name, value: roundTo9Dp(value)})
我是Ramda的创始人之一,而且我还是它的忠实粉丝。 但我认为它是一个库,当它能让代码更干净、更可维护时,就可以使用。 这里,最简单的版本不需要它。