Reputation: 155
I'm noob in functional programming (and ramda). And i have no idea how to make from this:
[{
"name":"SBRF IANUA EFS CC Integration",
"expand":false,
"check":"N",
"jsonDiffPath":"/repo/Dynamics/Business Service/SBRF IANUA EFS CC Integration",
"changeCount":1,
"items":[
{
"name":"CRP-37920",
"expand":false,
"check":"N",
"jsonDiffPath":null,
"changeCount":1,
"items":[],
"op":"MODIFY",
"oldSnapshot":"723012",
"newSnapshot":"948053",
"myChange":false
}
],
"id":"F5ZGK4DPF5CHS3TBNVUWG4ZPIJ2XG2LOMVZXGICTMVZHM2LDMUXVGQSSIYQESQKOKVASARKGKMQEGQZAJFXHIZLHOJQXI2LPNY======",
"objectId":"30263",
"group":"repo",
"category":"Dynamics",
"type":"Business Service"
}
]
something like this:
[
{
"name":"[CRP-37920] SBRF IANUA EFS CC Integration",
"expand":false,
"check":"N",
"jsonDiffPath":"/repo/Dynamics/Business Service/SBRF IANUA EFS CC Integration",
"changeCount":1,
"op":"MODIFY",
"oldSnapshot":"723012",
"newSnapshot":"948053",
"items":[],
"id":"F5ZGK4DPF5CHS3TBNVUWG4ZPIJ2XG2LOMVZXGICTMVZHM2LDMUXVGQSSIYQESQKOKVASARKGKMQEGQZAJFXHIZLHOJQXI2LPNY======",
"objectId":"30263",
"group":"repo",
"category":"Dynamics",
"type":"Business Service"
}
]
Each elements of "items" array should be merged with it parent (Object with inner array => into array of objects )
Thanks in advance)
Upvotes: 0
Views: 488
Reputation: 673
I'm new to Ramda, but thought I'd give it a go. My solution does include the custom name merge rule from your example.
let concatName = (key, parent, children) => key === 'name' ? `[${children}] ${parent}` : children;
const mergeItems = R.map((item ) => {
return R.mergeWithKey(concatName, item, R.mergeAll(R.prop('items',item)))}
)
Since it wasn't clear how "deep" nested items might be, nor what the merging rules should be in that case, I didn't make it go deeper.
Upvotes: 0
Reputation: 50797
One possibility, if I understand your requirements correctly would be something like this:
const alterOne = chain(
children => parent => map(merge(__, dissoc('items', parent)), children),
prop('items')
)
const alterAll = pipe(map(alterOne), flatten)
There's probably some good way to make the first function passed to chain
in alterOne
point-free, but this seems pretty readable to me already.
You can see this in the Ramda REPL.
Upvotes: 1
Reputation: 2638
// array of parents
const p = [
{
name: 'SBRF IANUA EFS CC Integration',
expand: false,
check: 'N',
jsonDiffPath: '/repo/Dynamics/Business Service/SBRF IANUA EFS CC Integration',
changeCount: 1,
items: [
{
name: 'CRP-37920',
expand: false,
check: 'N',
jsonDiffPath: null,
changeCount: 1,
items: [],
op: 'MODIFY',
oldSnapshot: '723012',
newSnapshot: '948053',
myChange: false
}
],
id: 'F5ZGK4DPF5CHS3TBNVUWG4ZPIJ2XG2LOMVZXGICTMVZHM2LDMUXVGQSSIYQESQKOKVASARKGKMQEGQZAJFXHIZLHOJQXI2LPNY======',
objectId: '30263',
group: 'repo',
category: 'Dynamics',
type: 'Business Service'
}
];
// define a function that describes how a child should merge with its parent
function merge(p) {
// p is the parent object
// c are all of p's children defined in items
const child = p['items'];
// on the item that we return we only want keys that appear in the parent
// create an array for the flattened results
const f = [];
child.forEach(el => {
let keys = Object.keys(p);
// clone the parent object
let c = Object.assign({}, p);
// basically unset the items since we are already iterating of them
child['items'] = [];
// now iterate over all of the childrens attrs described by the parents parameters
keys.forEach(k => {
// the childs value for each key
const val = el[k];
if (val !== undefined && val !== null) {
// handle your special cases in here, such as the name
if (k === 'name') {
c['name'] = '[' + el['name'] + '] ' + c['name'];
} else {
// default behavior for the non specific cases
c[k] = el[k]
}
}
});
// add the object to the array of flattened children
f.push(c);
});
return f;
}
// iterate over all of the parents and their children
// to do this we want to apply a map to all of the parents
const m = p.map(el => merge(el));
JS Bin of the example merge function.
As far as I know, you there isn't really a good reason to use something like lodash (_) or ramda for this, since it isn't a straight forward flatten/merge. You are wanting to do specific things depending on the key, so you will have to roll out a custom function to handle it.
The code that I provided is heavily documented and relatively straight forward, but for learnings sake here is a high level overview:
Upvotes: 0