I want to return an object containing only the keys which are passed via an array, For e.g., I have an array of keys,
const arr = ['a', 'b', 'c', 'd', 'e']
and an Object,
const obj = {
a: {
name: 'a',
capital: 'A'
},
g: {
name: 'g',
capital: 'G'
},
b: {
name: 'b',
capital: 'B'
},
m: {
c: {
name: 'c',
capital: 'C'
}
},
z: {
name: 'z',
capital: 'Z'
},
n: {
e: {
name: 'e',
capital: 'E'
}
},
o: {
f: {
d: {
name: 'd',
capital: 'D'
}
}
}
}
Now I want to return an Object which contains just the keys present in arr
, 'a', 'b', 'c', 'd' and 'e'
, so my resultant object will be,
{
a: {
name: 'a',
capital: 'A'
},
b: {
name: 'b',
capital: 'B'
},
c: {
name: 'c',
capital: 'C'
},
e: {
name: 'e',
capital: 'E'
},
d: {
name: 'd',
capital: 'D'
}
}
Approach:
I am approaching it like as shown below, but not getting the desired result,
function fetchValueByKey(object, key, result) {
if(typeof object !== 'object')
return result;
for(let objKey in object) {
if(key.indexOf(objKey) > -1) {
result[objKey] = object[objKey];
console.log(result);
} else {
result[objKey] = fetchValueByKey(object[objKey], key, result);
console.log(result)
}
}
}
console.log(fetchValueByKey(obj, arr, {}));
Please suggest me on how can I achieve this?
CodePudding user response:
Your code is good; you just need to return or output result after the loop. PLUS, there's no need for result[objKey] =
since you've already determined that objKey
is not in the list of keys you're looking for, so just call the function again to drill down the sub-object.
const arr = ['a', 'b', 'c', 'd', 'e']
const obj = { a: { name: 'a', capital: 'A' }, g: { name: 'g', capital: 'G' }, b: { name: 'b', capital: 'B' }, m: { c: { name: 'c', capital: 'C' } }, z: { name: 'z', capital: 'Z' }, n: { e: { name: 'e', capital: 'E' } }, o: { f: { d: { name: 'd', capital: 'D' } } } };
function fetchValueByKey(object, key, result) {
if(typeof object !== 'object')
return result;
for(let objKey in object) {
if(key.indexOf(objKey) > -1) {
result[objKey] = object[objKey];
//console.log(result);
} else {
fetchValueByKey(object[objKey], key, result);
//console.log(result)
}
}
return result;
}
console.log(fetchValueByKey(obj, arr, {}));
CodePudding user response:
You could get flat and filterd entries and build an object.
const
getFlatFilteredEntries = object => Object
.entries(object)
.flatMap(([k, v]) => 'name' in v // or other indicator of leaf object
? keys.includes(k)
? [[k, v]]
: []
: getFlatFilteredEntries(v)
),
keys = ['a', 'b', 'c', 'd', 'e'],
object = { a: { name: 'a', capital: 'A' }, g: { name: 'g', capital: 'G' }, b: { name: 'b', capital: 'B' }, m: { c: { name: 'c', capital: 'C' } }, z: { name: 'z', capital: 'Z' }, n: { e: { name: 'e', capital: 'E' } }, o: { f: { d: { name: 'd', capital: 'D' } } } },
result = Object.fromEntries(getFlatFilteredEntries(object));
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
CodePudding user response:
We can use JSON.stringify here to iterate over every nested object & we can check for the key is included in the array and add that in the object.
const obj = {
a: {
name: 'a',
capital: 'A'
},
g: {
name: 'g',
capital: 'G'
},
b: {
name: 'b',
capital: 'B'
},
m: {
c: {
name: 'c',
capital: 'C'
}
},
z: {
name: 'z',
capital: 'Z'
},
n: {
e: {
name: 'e',
capital: 'E'
}
},
o: {
f: {
d: {
name: 'd',
capital: 'D'
}
}
}
}
const arr = ['a', 'b', 'c', 'd', 'e'];
function getObjects(arr, obj) {
const a = {};
let str = JSON.stringify(obj, (key, value) => {
if(arr.includes(key)) {
a[key] = value;
return value
}
return value
});
return a;
}
console.log(getObjects(arr, obj));
Solved a similar problem with JSON.stringify is really helpful when playing with objects. What is the efficient way to shallow clone an object using JavaScript?
CodePudding user response:
Object.keys(obj).filter(Key=>arr.includes(Key)).Map(Key=>obj[Key])
That should work!
PS: zorry for the miss spelling but writing from m'y phone