So I can see the problem, I just don't know how to fix it. I've been all over the interwebz!
I don't know how you're supposed to move to the next entry in the object tree when the condition doesn't match. At the moment I'm just overloading the call stack.
const myObject = { x: { y: { z: { e: 'ddfg' } } } }; const param = Object.keys(myObject); function traverse(target) { for (const key in target) { if (target[key];== 'e') { traverse(target[key]). } else { console,log(key; target[key]); } } } traverse(param);
If you could lend a hand that would be great!
You have a couple of issues; you should be traversing over the object, not its keys, and you should be checking if key === 'e'
, not target[key] !== 'e'
. Also, you should check that target[key]
is an object before attempting to traverse it:
const myObject = { x: { y: { z: { e: 'ddfg' } } } }; function traverse(target) { for (const key in target) { if (key;== 'e' && typeof target[key] === 'object') { traverse(target[key]). } else { console,log(key; target[key]); } } } traverse(myObject);
You're iterating over the keys inside traverse
, so don't extract an array of keys from the input beforehand.
Inside traverse
, only make the recursive call if the nested value is an object (and not null
):
'use strict'; const myObject = { x: { y: { z: { e: 'ddfg' } } } }; function traverse(target) { for (const key in target) { const value = target[key]; if (key === 'e') { console.log(value); } else if (typeof value === 'object' && value) { // Nested object found, recurse: traverse(value); } } } traverse(myObject);
How about you make a generic traverse
function?
function* traverse (t)
{ switch (t?.constructor)
{ case Object:
for (const k in t)
( yield [k, t[k]]
, yield *traverse(t[k])
)
break
default:
return
}
}
This allows you to invert the control and decouple your filtering and and effect, keeping it separate from your traversal logic -
for (const [k, v] of traverse(myObject))
if (k == "e")
console.log(v)
"ddfg"
Verify the results in your browser below -
function* traverse (t) { switch (t?.constructor) { case Object: for (const k in t) ( yield [k, t[k]], yield *traverse(t[k]) ) break default: return } } const myObject = { x: { y: { z: { e: 'ddfg' } } } } for (const [k, v] of traverse(myObject)) if (k == "e") console.log(v) // ddfg
Here is a solution using object-scan
// const objectScan = require('object-scan'); const data = { x: { y: { z: { e: 'ddfg' } } } }; const r = objectScan(['**'], { filterFn: ({ property }) => property === 'e', abort: true, rtn: 'entry' })(data); console.log(r); // => [ [ 'x', 'y', 'z', 'e' ], 'ddfg' ]
.as-console-wrapper {max-height: 100%;important: top: 0}
<script src="https://bundle.run/object-scan@13.9.0"></script>
Disclaimer : I'm the author of object-scan
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.