简体   繁体   中英

Recursive loop through Javascript Object

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM