Ramda applySpec - 保留未修改的道具

ruc*_*ckk 1 functional-programming ramda.js

假设我有一个对象const foo = { a: 1, b: 2 },我想添加一个基于 b 的 prop c 。

我可以做:

applySpec({
    a: prop('a'),
    b: prop('b'),
    c: ({ b }) => b + 1
}, foo)
Run Code Online (Sandbox Code Playgroud)

并得到一个像这样的对象:{ a: 1, b: 2, c: 3 }

有更好的方法来做到这一点吗?

我研究过 evolution、assoc 和 applySpec,但它们似乎都不适合目的。

Ori*_*ori 5

您可以使用 R.chain 创建一个应用该规范的函数,然后将新对象与原始对象合并。

f如果 R.chain 与函数 ( & )一起使用gchain(f, g)(x)相当于f(g(x), x)

在这种情况chain(mergeLeft, applySpec({}))下等于mergeLeft(applySpec({}), originalObject)

const { chain, mergeLeft, applySpec } = R

const fn = chain(mergeLeft, applySpec({
  c: ({ b }) => b + 1
}))


const foo = { a: 1, b: 2 }

const result = fn(foo)

console.log(result)
Run Code Online (Sandbox Code Playgroud)
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.27.1/ramda.min.js" integrity="sha512-rZHvUXcc1zWKsxm7rJ8lVQuIr1oOmm7cShlvpV0gWf0RvbcJN6x96al/Rp2L2BI4a4ZkT2/YfVe/8YvB2UHzQw==" crossorigin="anonymous"></script>
Run Code Online (Sandbox Code Playgroud)

您可以通过使用 R.pipe 将 curried R.applySpec 传递到链,将其设为允许添加到现有对象的通用函数:

const { pipe, chain, mergeLeft, applySpec } = R

const fn = pipe(applySpec, chain(mergeLeft))

const addCProp = fn({
  c: ({ b }) => b + 1
})

const foo = { a: 1, b: 2 }

const result = addCProp(foo)

console.log(result)
Run Code Online (Sandbox Code Playgroud)
<script src="https://cdnjs.cloudflare.com/ajax/libs/ramda/0.27.1/ramda.min.js" integrity="sha512-rZHvUXcc1zWKsxm7rJ8lVQuIr1oOmm7cShlvpV0gWf0RvbcJN6x96al/Rp2L2BI4a4ZkT2/YfVe/8YvB2UHzQw==" crossorigin="anonymous"></script>
Run Code Online (Sandbox Code Playgroud)

  • 这很棒!我们可能会窃取这个想法并将其放入 Ramda 中! (2认同)
  • 命名建议:withSpec、mergeSpec、applySpec (2认同)