R
R
rebyatyonok2017-05-05 13:33:26
JavaScript
rebyatyonok, 2017-05-05 13:33:26

Why doesn't the recursion stop?

There is a JS object of unknown nesting. That is, inside it, among other properties, there are more objects, and in them, in turn, there are more objects, etc. It looks something like this:

var trunk = {
    listItem1: 1,
    listItem2: {
        subListItem: 1,
        subListItem2: {
            subsubListItem1: 1,
            subsubListItem2: 2
        }
    },
    listItem3: 3
}

You need to do the following with this object: extract from it all properties whose values ​​are equal to 1, and write the path to them as a trace. way: ListItem2 > subListItem2 > subsubListItem1. That is, walk through the entire object and its sub-objects. I wrote this function:
function search(obj) {
    for (var key in obj) {
        if (obj[key] == "1") {
            console.log(key + '>')
        } else if (typeof obj[key] == "object") {
            console.log(this + '>');
            return search(this);
        } else {
            // "I dont need this"
        }
    }
};

That is, the function checks the values. First, it is equal to one, then it checks if it is an object, and if it is neither one nor the other, it does nothing. If it is an object, I need to loop the function so that it starts executing itself and stops when there are no objects or units left. My mistake is that while checking for an object, it loops indefinitely with a "speechSythesis" error and an infinite alert, or "Maximum call stack size exceeded" in the console (Chrome). What's my mistake? The answer would be detailed and with explanations.
Ideally, we would like to have a function that (theoretically, because in practice the computer will probably freeze) will check an object with n number of n-nesting properties.

Answer the question

In order to leave comments, you need to log in

2 answer(s)
N
Nicholas, 2017-05-05
@rebyatyonok

return search(this) ?
you are calling the function with the current context. And you need to call with the object in which you want to search, i.e. obj[key]. Well, return is certainly not needed. Because otherwise you will exit the loop after the first hit on the object.

I
Islam Ibakaev, 2017-05-05
@devellopah

I took the liberty of adding a second argument (to increase the string indicating the path to the property)
if you don't mind, then you can do something like this

const trunk = {
    listItem1: 1,
    listItem2: {
        subListItem: 1,
        subListItem2: {
            subsubListItem1: 1,
            subsubListItem2: 2
        }
    },
    listItem3: 3
};

const ones = [];

traverse(trunk, 'root');

function traverse(obj, path) {
  for(let key in obj) {
    const newPath = path + ' > ' + key;
    
    if (obj[key].constructor.name === "Object") {
      
      // console.log(newPath);
    	return traverse(obj[key], newPath);
    }
    
    if(obj[key] == "1") {
    	ones.push(newPath);
    }
    
  }
  
  console.log('properties\' pathes which value is equal to 1 \n\n' , ones);
}

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question