I have an array with nested Objects with dynamic keys similar to this
const arr = [
{
"x1": [
{
"x1-point1": [
{
"value": 200,
"angle": 20
},
{
"value": 23,
"angle": 90
}
]
},
{
"x1-point2": [
{
"value": 54,
"angle": 0
}
]
},
{
"x1-point3": [
{
"value": 79
}
]
}
]
},
{
"x2": [
{
"x2-point1": [
{
"value": 12
}
]
},
{
"x2-point2": [
{
"value": 24
}
]
},
{
"x2-point3": [
{
"value": 36
}
]
}
]
}
]
Im trying to search the value and get the parent keys along with the resultant child What i tried was this
val = 200
arr.filter(r => !!Object.values(r).find(t => t.value == val))
My expected result would be
[
{
"x1": [
{
"x1-point1": [
{
"value": 200,
"angle": 20
}
]
}
]
}
]
What is that im doing wrong here, Im filtering the innermost child matching with the string and getting its parent keys
CodePudding user response:
Presented below is one possible way to achieve the desired objective.
Code Snippet
// find needle "n" in hayStack "hs"
const myFind = (n, hs, res=[]) => {
// search "hs" array for value "n"
const foundIt = hs.find(ob => 'value' in ob && ob.value === n);
// if found, add it to "res" array & return
if (foundIt) {
res.push(foundIt);
return res;
} else {
// not-found - so, go to inner/nested level
// hold result in "ires" - intermediate result array
let ires = [];
// for each object "ob" in "hs" array
// iterate over "ob"'s key-value pairs
// filter out pairs where "v" is not an array
hs.forEach(ob => {
Object.entries(ob)
.filter(([k, v]) => v && Array.isArray(v))
.forEach(([k, v]) => {
// make recursive call, this time "v" is the hayStack
const ores = myFind(n, v);
// if recursion result is present, accumulate it to "ires"
if (ores && ores.length > 0) {
ires.push({ [k] : ores });
};
})
});
// return if there is intermediate result
if (ires.length > 0) return ires;
};
// value "n" not found
return false;
};
const arr = [{
"x1": [{
"x1-point1": [{
"value": 200,
"angle": 20
},
{
"value": 23,
"angle": 90
}
]
},
{
"x1-point2": [{
"value": 54,
"angle": 0
}]
},
{
"x1-point3": [{
"value": 79
}]
}
]
},
{
"x2": [{
"x2-point1": [{
"value": 12
}]
},
{
"x2-point2": [{
"value": 24
}]
},
{
"x2-point3": [{
"value": 36
}]
}
]
}
];
console.log('find value: 200 result: ', myFind(200, arr));
console.log('find value: 54 result: ', myFind(54, arr));
console.log('find value: 36 result: ', myFind(36, arr));
console.log('find value: 205 result: ', myFind(205, arr));
.as-console-wrapper { max-height: 100% !important; top: 0 }
Explanation
Inline comments added to the snippet above.
PS: If you'd like to add value to stackoverflow community,
Please consider reading: What to do when my question is answered Thank you !