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
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 !