Reputation: 71
I'm trying to learn more about functional programming and wondered how to convert this function that re orders the key values of an object alphabetically into a new function using Ramda compostion. I'm able to do it using JS but it's part of a more complex fn i'm composing that i'd like to use Ramda to solve in keeping with rest of code base in prod.
const reOrder = Object.keys(obj).sort().reduce(
(obj, key) => {
obj[key] = obj[key];
return obj;
},
{}
);
Upvotes: 0
Views: 60
Reputation: 50807
A few points:
First of all, that code doesn't work. Your accumulator is named obj
, which will shadow the obj
from outside the scope, so obj [key] = obj [key]
is simply saying take the key from the accumulator. You could fix this in a few ways:
You could rename the original object:
const reOrder = Object.keys(orig).sort().reduce(
(obj, key) => {
obj[key] = orig[key];
return obj;
},
{}
);
You could rename the accumulator:
const reOrder = Object.keys(obj).sort().reduce(
(acc, key) => {
acc[key] = obj[key];
return acc;
},
{}
);
Or, as it looks like you're trying to modify the value in place, you could try something really nasty like the following:
const reOrder = Object.keys(obj).sort().reduce(
(obj, key) => {
const temp = obj[key]
delete obj[key]
obj[key] = temp;
return obj;
},
obj
);
But the FP gods would heap scorn upon you and upon your children's children's children to the seventh generation should you choose to do this. Immutability is a key tenet of functional programming.
Functional programming is about..., well, functions. When a functional programmer looks for how to do something, the first question is not how to perform it procedurally. It's how to write a function to do so.
So with Ramda, we'd usually ask how we'd write a function to do this. That's an easy modification. It might look like this:
const reorder = (obj) => Object .keys (obj) .sort() .reduce(
(res, key) => {
res [key] = obj [key]
return res
},
{}
)
Even though the language defines a traversal order having to do with the order in which the keys are declared, objects are usually best thought of as unordered collections. Ramda's equality checking, for instance, does not distinguish between {a: 1, b: 2}
and {b: 2, a: 1}
.
So using Ramda to do this feels inappropriate. If there is a Ramda genie underneath all the magic, it would have to be saying, "You want me to do what?!"
However, if you still want to pursue this, we can write this function in a simple manner using Ramda's tools:
const reorder = compose (fromPairs, sortBy(head), toPairs)
console .log (
reorder ({b: 1, c: 2, d: 3, a: 4})
)
<script src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.27.1/ramda.min.js"></script>
<script>const {compose, fromPairs, sortBy, head, toPairs} = R </script>
toPairs
turns our object into an array of name-value pairs such as [['b', 1], ['c', 2], ...]
. Then sortBy (head)
sorts that array by the first value of the pair (the original key.) And finally fromPairs
stitches those key-value pairs back into an object.
Upvotes: 3