As the discussion on the answer from customcommander shows, there are two different possible interpretations.
If you want to just receive [1, 2, 3, 5]
, then you can do it as customcommander does, or the way I would choose:
const fn1 = lift (append) (prop ('newItem'), prop ('list'))
But if you wanted something like {list: [1, 2, 3, 5], newItem: 5}
, then you might use the above inside applySpec
and combine that with a merge, like this:
const fn2 = chain (mergeLeft, applySpec ({list: fn1}))
Here's a snippet:
const fn1 = lift (append) (prop ('newItem'), prop ('list'))
const fn2 = chain (mergeLeft, applySpec ({list: fn1}))
const data = {list: [1, 2, 3], newItem: 5}
console .log (fn1 (data)) //=> [1, 2, 3, 5]
console .log (fn2 (data)) //=> {list: [1, 2, 3, 5], newItem: 5}
.as-console-wrapper {max-height: 100% !important; top: 0}
<script src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.28.0/ramda.min.js"></script>
<script> const {lift, append, prop, chain, mergeLeft, applySpec} = R </script>
This second one is a little unwieldy, once you inline fn1
. It repeats the property list
in two places, and that always bothers me. But I don't have a good solution at the moment.
I've several times wanted a combination of R.evolve
and R.applySpec
, which works on the outside like evolve
, letting you specify only the properties which need to change, but whose transformation functions are given the whole input object, and not just the corresponding property.
With something like that, this might look like
const f3 = evolveSpec ({
list: ({list, newItem}) => [...list, newItem]
})
or using the above:
const f3 = evolveSpec ({
list: lift (append) (prop ('newItem'), prop ('list'))
})
I think this might be a useful candidate for inclusion in Ramda.