Hi ramda folks,
I’m new to rambda and I would like to transform this JSON:
{
‘2’ : { ‘name': ‘two’},
‘1’ : {’name’ : ‘one’}
}
into some sorted iterable (list?) like this:
[
{ id: ‘1’, name: ‘one'},
{ id: ‘2’, name: ’two'}
]
In other words I need to:
How can I do this in an elegant way? All my attempts become quite imperative.
Thanks!
R.pipe(
R.mapObjIndexed( R.useWith(R.flip(R.assoc('id')), R.identity, Number)),
R.values,
R.sortBy(R.prop('id'))
)
R.pipe
for every time.
@CrossEye Would you help me understand your suggestion, please?
f = R.assoc('id')
g = R.zipWith( f );
R.converge(g, R.keys, R.values);
I understand that we are partially applying arguments.assoc
takes 3 arguments. The last one is the list itself.
But what happens with the second one?
R.zipWith
with a function that accepts two arguments (1. and 2. above) will then be expecting one array of 1. and one array of 2.
R.keys
gives you the array of 1.s and R.values
an array of 2.s
@alesch I also found CrossEyes answer pretty astounding, so I picked it apart in the REPL. Let's start with converge
:
//converge(f, a, b)(x) === f(a(x), b(x))
//so:
R.converge(R.zipWith(R.assoc('id')), R.keys, R.values)(x) //===
R.zipWith(R.assoc('id'))(R.keys(x), R.values(x)) //===
R.zipWith(R.assoc('id'), R.keys(x), R.values(x))
Now R.keys
and R.values
both produce lists. One containing the ID's (keys
) and the other containing objects (values
). And as it happens, R.zipWith(f)
wants two lists, and it'll pass a pair of items (taken from both lists) into f
so that f
may produce a single item for the returned list.
In this case we use R.assoc('id')
as our f
(zipper function), which will receive the ID from the first list, and the object from the second and return a new object on which the "id" property will have been set.
Object.keys
guarantee an order?