As usual, customcommander gives an excellent answer. Ramda's evolve
is designed for exactly that and, in the simple case, can allow for an entirely point-free answer.
One of Ramda's authors, I very much like its functions. But it should be noted that it's quite easy to build your own versions of many, including this one, especially if you're in the simple situation where you only care about updating keys at the root of your object. (Ramda's recurs into nested spec objects, which is at least a bit more involved.)
So, if you didn't have Ramda handy, you might easily write a custom version of this function like this:
const evolve = (spec, keys = Object .keys (spec)) => (obj) =>
Object .entries (obj) .reduce (
(a, [k, v]) => ({...a, [k]: keys .includes (k) ? spec [k] (v) : v})
, {}
)
const upperCase = str => str.toUpperCase() //for the name
const add10 = int => int + 10 // for the age
const addFriend = (value) => (list) => [...list,value] // adding a friend
const person = {name: 'John', eys: 'blue', age: 30, friends: [], hair: 'red'}
console .log (
evolve ({name: upperCase, age: add10, friends: addFriend('Lucas')}) (person)
)
This is far from the most performant code. An excellent article from Rich Snapp explains why and how to fix it. But I personally would stick with this unless this becomes a bottleneck in my application.
Of course, as customcommander also points out, there are Ramda functions for each of your helpes: toUpper
, add
, append
(closer to the above implementation than prepend
.)
A more complete discussion on the topic VLAZ raised in a comment can be found in https://stackoverflow.com/a/33130194/1243641.