Question: Functional programming / Ramda: Creating a new object by picking nested properties

Question

Functional programming / Ramda: Creating a new object by picking nested properties

Answers 1
Added at 2017-01-03 16:01
Tags
Question

Functional programming newbie here. I have this object:

{ 
  _id: '2014d5db-55dc-4078-ae87-382c226d0785',
  _source: { 
    phone: '00447827434313',
    ...
  } 
}

In the end I want to have it in this format:

{ 
  id: '2014d5db-55dc-4078-ae87-382c226d0785',
  phone: '00447827434313',
  ...
}

Basically extracting _source, and renaming _id to id.

I created this function below which works, but I'm trying use only Ramda's functions instead of creating new objects by hand. I assume it's more "functional" way, let me know if it doesn't really matter.

const test = o => merge(o._source, { id: o._id })

Thanks very much

Answers
nr: #1 dodano: 2017-01-03 17:01

I don't think there's a particular built-in Ramda function for that. But it's not hard to write one on top of lensPath, view, and map:

const remap = R.curry((desc, obj) => R.map(path => R.view(R.lensPath(path), obj), desc));

const myExtract = remap({
  id: ['_id'],
  phone: ['_source', 'phone']
});

myExtract(input);
//=> {"id": "2014d5db-55dc-4078-ae87-382c226d0785", "phone": "00447827434313"}

It only works this simply if your output is described as a flat list of fields (of course their properties could themselves be objects.) But one where you pulled from nested paths and pushed to nested paths would not be too much harder to write. The user API would be uglier, though, I imagine.

I don't see any clean way to make this points-free and still retain readability. Perhaps someone else might manage that, but I think this is already pretty nice.

You can see this in action on the Ramda REPL.

Source Show
◀ Wstecz