Home > OS >  Getting depth of recursive function React.js/JavaScript
Getting depth of recursive function React.js/JavaScript

Time:10-04

I am trying to solve a JavaScript/React.js exercice to practice recursive functions in which you have an input object (that can have multiple depth levels) and you want to output a "tree" with the object content like below:

//Input object
const input = {
  key1: {
    key11: 'v11',
  },    
  key2: {
    key21: {
      key211: 'v211',
    },
  },
  key3: 'v3',
}

/* Desired output:
key1:
--key11: v11
key2:
--key21:
----key211: v211
key3: v3
*/

I have managed to develop the App.jsx component that makes the recursive calls:

class App extends React.Component {  
    renderObject(input, level=0){
    return (Object.entries(input).map((item, index) => {
      if(typeof item[1] === "string"){
        let object = <div key={`${item[0]}-level-${level}`}><span>{"--".repeat(level)}</span>{item[0]}: {item[1]}</div>;
        level = 0;
        return object;
      } else {
        let object = <div key={`${item[0]}-level-${level}`}><span>{"--".repeat(level)}</span>{item[0]}: { this.renderObject(item[1],   level)}</div>
        return (object)
      }
    }))
  }
  
  render() {
    return (
      <div>
            {this.renderObject(input)}
      </div>
    )
  }
}

ReactDOM.render(<App />, document.querySelector("#app"))

The problem I am facing is that the level I have implemented is not showing the real depth, because it also increments in each iteration in the first level (when it should remain 0).

/* Obtained output: 
key1:
--key11: v11
--key2:
----key21:
------key211: v211
----key3: v3
*/

How could I solve this?

CodePudding user response:

Converting my comment to an answer, the problem is related to mutating the value of level with level and level = 0 in the body of the recursive function. Looking at the printed result, the goal is for each level to have the same indentation, so with level, future siblings in the loop at the same level will be indented at increasing distances. level = 0 might have been an attempt at rectifiying this problem, but it doesn't work because level shouldn't be 0 once the recursion starts.

The solution is to treat level as effectively immutable during the body of the function, then use level 1 as the parameter to set up the child recursive calls to the appropriate level.

Here's the code:

class App extends React.Component {
  renderObject(o, level = 0) {
    return Object.entries(o).map(([k, v]) => (
      <div key={[k, v, level].join("-")}>
        <span>{"--".repeat(level)}</span>
        {k}:{" "}
        {typeof v === "object"
          ? this.renderObject(v, level   1)
          : v}
      </div>
    ));
  }

  render() {
    return <div>{this.renderObject(this.props.tree)}</div>;
  }
}

const tree = {
  key1: {
    key11: "v11",
  },
  key2: {
    key21: {
      key211: "v211",
    },
  },
  key3: "v3",
};
ReactDOM.render(
  <App tree={tree} />,
  document.querySelector("#app")
);
#app {
  font-family: monospace;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-standalone/6.26.0/babel.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.2/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.2/umd/react-dom.production.min.js"></script>
<div id="app"></div>

CodePudding user response:

Do level 1 instead of level

  • Related