Recursively Find Keys On An Object
I have a javascript object structured like this; brand: { group: { subGroup: { items: [] }, otherSub: { items: [] } } } Given an array of keys ['
Solution 1:
Here's a pretty sketchy way that works.
const find = (keys, obj) => {
const string = JSON.stringify(obj);
return keys.reduce(({ present, missing }, key) => {
const match = string.match(new RegExp(`"${key}":`));
if (match) {
present.push(key);
} else {
missing.push(key);
}
return { present, missing };
}, { present: [], missing: [] });
}
Solution 2:
You can use this function made for you ;)
var getAttrs = function(obj) {
return [].concat.apply([], Object.keys(obj).map(function (key) {
var results = [key]
if (typeof obj[key] === 'object') {
Array.prototype.push.apply(results, getAttrs(obj[key]))
}
return results
}))
}
It return the list of properties and children properties.
getAttrs({brand: {
group: {
subGroup: {
items: []
},
otherSub: {
items: []
}
}
}})
> ["brand", "group", "subGroup", "items", "otherSub", "items"]
And you can use it like so:
var lookingFor = ['brand', 'group', 'newGroup', 'newSubGroup']
var existings = getAttrs(obj)
var missings = []
var presents = []
lookingFor.forEach(attr => {
if (existings.indexOf(attr) === -1) {
missings.push(attr)
} else {
presents.push(attr)
}
})
Solution 3:
I wrote a function to recursively get unique keys from a nested object, then filtered the array of all the keys you mentioned checking which were present in the result of my function.
var thisObject = {
brand: {
group: {
subGroup: {
items: []
},
otherSub: {
items: []
}
}
}
};
var arr_full = ['brand', 'group', 'newGroup', 'newSubGroup'] ;
var key_array = [];
function addToKeyArray( key_array, object ){
for( var key in object ){
// only get unique keys
if( key_array.indexOf( key ) === -1 ){
key_array.push( key );
}
// concat the result of calling this function recurrsively on object[key]
key_array.concat( addToKeyArray( key_array, object[key] ) );
}
return key_array;
}
var test = addToKeyArray( [], thisObject );
var missing = arr_full.filter( function( el ) {
return test.indexOf( el ) < 0;
});
console.log( test );
console.log( missing )
Solution 4:
You can create recursive function using for...in
loop inside another function and return object as result..
var obj = {"brand":{"group":{"subGroup":{"items":[]},"otherSub":{"items":[]}}}}
var keys = ['brand', 'group', 'newGroup', 'newSubGroup'] ;
function findKeys(data, keys) {
keys = keys.slice();
function findPresent(data, keys) {
var result = []
for(var i in data) {
if(typeof data[i] == 'object') result.push(...findPresent(data[i], keys))
var index = keys.indexOf(i);
if(index != -1) result.push(...keys.splice(index, 1))
}
return result
}
return {present: findPresent(data, keys), missing: keys}
}
console.log(findKeys(obj, keys))
Solution 5:
To keep things clean and readable you can use "for in", inside a nested function for your recursion.
function recur(obj) {
let preMiss = {
present: [],
missing: []
}
let root = traverse => {
for (let key in traverse) {
if (Array.isArray(traverse[key].items)) {
preMiss.missing.push(key);
}
if (typeof traverse[key] === 'object' && !Array.isArray(traverse[key].items)) {
preMiss.present.push(key);
root(traverse[key])
}
}
}
root(obj);
return preMiss;
}
const object = {
brand: {
group: {
subGroup: {
items: []
},
otherSub: {
items: []
}
}
}
}
console.log(Object.entries(recur(object)));
Post a Comment for "Recursively Find Keys On An Object"