Last active
March 1, 2021 14:25
-
-
Save gyenabubakar/f94c86d3ddb785cd801ce3bb3be22fa6 to your computer and use it in GitHub Desktop.
Given an object 'fakeObj'; loop though all the properties of 'fakeObj' object and add them into an array. If there's a nested object, it should be removed from its parent object and added to the array directly. So, basically, all objects should be detached and made stand-alone in the final array, regardless of their position in the given object …
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// example object | |
const fakeObj = { | |
key1: { | |
prop1: true, | |
prop2: 34, | |
prop3: 'Hello', | |
prop4: [], | |
}, | |
key2: { | |
prop1: true, | |
prop2: { | |
subprop1: [], | |
subprop2: 234, | |
subprop3: { | |
a: [], | |
b: false, | |
}, | |
}, | |
prop3: 'Hello', | |
prop4: [], | |
}, | |
key3: { | |
prop1: true, | |
prop2: 34, | |
prop3: 'Hello', | |
prop4: [], | |
}, | |
}; | |
// function to return the final array of standalone objects | |
function mergeObjectsToArray(object) { | |
// array of standalone objects | |
const arr = []; | |
// go through the passed object | |
// check if properties are objects | |
// detach them and add them directly in the target array, 'arr' | |
validateAndAddObj(object, arr); | |
// return array of standalone objects | |
return arr; | |
} | |
function validateAndAddObj(object, targetArray) { | |
// for every first-level property | |
for (const prop in object) { | |
// object to keep track of element | |
const element = {}; | |
// check if property is indeed a property of object | |
if (Object.hasOwnProperty.call(object, prop)) { | |
for (const subProp in object[prop]) { | |
// check if the property is a reference to an object; not an array | |
if ( !(typeof object[prop][subProp] === 'object' && !Array.isArray(object[prop][subProp]) ) ) { | |
// if yes, run though the object again | |
validateAndAddObj(object[prop][subProp]); | |
} else { | |
// if it's not an object, add it as a property to tracking object, 'element' | |
element[subProp] = object[prop][subProp]; | |
targetArray.push(element); | |
break; | |
} | |
} | |
} | |
} | |
} | |
module.exports.mergeObjectsToArray = mergeObjectsToArray; | |
module.exports.validateAndAddObj = validateAndAddObj; |
jherr
commented
Feb 12, 2021
@jherr This yields a result that's very close to the expect result.
In this result:
[
{ prop1: true, prop2: 34, prop3: 'Hello' },
{ b: false },
{ subprop2: 234 },
{ prop1: true, prop3: 'Hello' },
{ prop1: true, prop2: 34, prop3: 'Hello' }
]
You'll see that all the arrays have been omitted. For instace, the property prop4
in key1
, which is an array, doesn't appear in the flattened object (array).
They're supposed to be included.
Ah, ok:
function validateAndAddObj(object, targetArray) {
if (typeof object === "object") {
const element = {};
for (const prop in object) {
if (
typeof object[prop] === "object" &&
Array.isArray(object[prop]) === false
) {
validateAndAddObj(object[prop], targetArray);
} else {
element[prop] = object[prop];
}
}
if (Object.keys(element).length) {
targetArray.push(element);
}
}
}
Or perhaps more preferable:
// example object
const fakeObj = {
key1: {
prop1: true,
prop2: 34,
prop3: "Hello",
prop4: [],
},
key2: {
prop1: true,
prop2: {
subprop1: [],
subprop2: 234,
subprop3: {
a: [],
b: false,
},
},
prop3: "Hello",
prop4: [],
},
key3: {
prop1: true,
prop2: 34,
prop3: "Hello",
prop4: [],
},
};
// function to return the final array of standalone objects
export function mergeObjectsToArray(
object: Record<string, unknown>
): Record<string, unknown>[] {
// array of standalone objects
const arr = [];
// go through the passed object
// check if properties are objects
// detach them and add them directly in the target array, 'arr'
validateAndAddObj(object, arr);
// return array of standalone objects
return arr;
}
export function validateAndAddObj(
object: Record<string, unknown>,
targetArray: Record<string, unknown>[]
): void {
if (typeof object === "object") {
const element = {};
for (const prop in object) {
if (
typeof object[prop] === "object" &&
Array.isArray(object[prop]) === false
) {
validateAndAddObj(object[prop] as Record<string, unknown>, targetArray);
} else {
element[prop] = object[prop];
}
}
if (Object.keys(element).length) {
targetArray.push(element);
}
}
}
console.log(mergeObjectsToArray(fakeObj));
@jherr you're the man! problem solved!! Thank you sir!
So, at the end of the day. Two big takeaways from me on this:
- Recursion was probably unavoidable here. Sadly. You use a stack to avoid the recursion. But recursion is using a stack anyway, so your just trading your own version of a stack for the language's stack, which is needless complexity.
- I think the real issue was around the
subProp
stuff. Generally with recursion you want to do with the current level of recursion and not drill-down. You leave the drilling down to the next level of recursion.
Hope that helps ... a little.
Oh okay. It helps, a lot. I'm grateful.
I'm very gratefulful..
Thanks
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment