Open R35007 opened 4 months ago
I believe you want to be using just-extend
, not just-merge
. Try extend(true, obj1, obj2)
.
I believe you want to be using
just-extend
, notjust-merge
. Tryextend(true, obj1, obj2)
.
Tried that as well. still not getting the expected result
What is the difference between expected and what you are getting exactly?
{ "appName": "React", "tags": ["frontend", "mfe"], "fields": { "appName": { "type": "checkbox", "value": true, "label": "Confirm" }, "template": { "type": "radio", "options": [ { "label": "opt1", "value": "value1" }, { "label": "opt2", "value": "value2" }, { "label": "opt3", "value": "value3" }, { "label": "opt4", "value": "value4" }, { "label": "opt5", "value": "value5" } ] }, "projectName": { "type": "textbox" }, "skipInstall": { "type": "checkbox", "label": "Should Skip Install ?" } } }
Have already share u what I get and what is expected. the arrays are not merging. its just replacing it on index.
This is what I get
{
"appName": "React",
"tags": ["frontend"],
"fields": {
"appName": { "type": "checkbox", "value": true, "label": "Confirm" },
"template": {
"type": "radio",
"options": [{ "value": "value1" }, { "label": "opt2", "value": "value2" }, {}, { "label": "opt4", "value": "value4" }]
},
"skipInstall": { "type": "checkbox", "label": "Should Skip Install ?" }
}
}
Ah yeah I was also noticing that! But in your "expected" version you left a bit with that behavior so I thought that is what you wanted.
const isArray = (val: unknown) => !!(val && typeof val === 'object' && Array.isArray(val));
const isPlainObject = (val: unknown) => !!(val && typeof val === 'object' && !isArray(val));
const isCollection = (val: unknown): val is Array<object> => !!(val && isArray(val) && val.length && val.every(isPlainObject));
const isMatrix = (val: unknown): val is Array<unknown[]> => !!(val && isArray(val) && val.length && val.every(isArray));
const isPrimitive = (val: unknown) => !!(val && typeof val !== 'object');
const getValuesByKey = (args: object[], keyName: string) =>
args
.map((obj) =>
Object.entries(obj)
.filter(([key]) => key === keyName)
.map(([, value]) => value)
)
.flat();
const getValuesByIndex = (args: Array<unknown[]>, index: number) => args.map((arr) => arr[index]).flat();
function mergeDeep(...args: unknown[]): object | unknown[] {
if (isCollection(args)) {
const allKeys = args.map((obj) => Object.entries(obj).map(([key]) => key)).flat();
const entries = allKeys.map((key) => {
const values = getValuesByKey(args as object[], key);
return values.every(isPrimitive) ? [key, values[values.length - 1]] : [key, mergeDeep(...values)];
});
return Object.fromEntries(entries);
}
if (isMatrix(args)) {
const maxArrayLength = args.reduce((acc, item) => (acc >= item.length ? acc : item.length), 0);
return [...Array(maxArrayLength).keys()].map((index) => mergeDeep(...getValuesByIndex(args, index))).flat();
}
return [...new Set(args)].filter(Boolean);
}
export default mergeDeep;
This is what I have comeup with. Feel free to use it for merge or expand
Sample Input
Expected Output
But What I get is