If you are using (or interested in using) Ramda (disclaimer: I'm one if its primary authors), this might work for you. Ramda does not have a deepMap
function, but it's easy to write one. And using that, your transformation function is a one-liner:
const deepMap = (fn) => (obj) =>
is (Object, obj) ? map (deepMap (fn)) (obj) : fn (obj)
const transform = compose(applySpec, deepMap (compose (path, split('.'))))
const objToTransform = {a: "aValue", b: {c: "cValue", d: "dValue"}}
const filteringObj = {field1: "a", field2: {subfield1: "b.c", subfield2: "b.d"}}
console .log (transform (filteringObj) (objToTransform))
<script src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.27.0/ramda.js"></script>
<script> const {is, map, compose, applySpec, path, split } = R </script>
The key point here is applySpec
, which you could use directly with a slightly different format of filteringObj
. This would yield your desired results:
applySpec ({
field1: path (["a"]),
field2: {
subfield1: path (["b", "c"]),
subfield2: path (["b", "d"])
}
}) (objToTransform)
The remainder of the transform
function is simply to convert the filteringObj
into that form above.
If you want to keep calling it as asked in the question, that is as transform (objToTransform, filteringObj)
rather than trasform (filteringObj) (objToTransform)
, it's only slightly more complex:
const transform = (objToTransform, filteringObj) =>
applySpec(deepMap (compose (path, split('.'))) (filteringObj)) (objToTransform)
You can write your own versions of those Ramda functions, it's mostly easy. But a version of applySpec
which works on nested properties would be a bit more difficult.