Schorsch
Schorsch

Reputation: 11

Recursive "parsing" function in javascript

I'm trying to create a kind of recursive parsing function, but it does not work as it should.

The array to be parsed:

gridArray = [
    {
        type:"row",
        text:"row1",
        cols: [
            {
                type:"col",
                text:"col1",
                rows: [
                    {
                        type:"row",
                        text:"row1 nested",
                        cols: [{}]
                    }
                ]
            },
            {
                type:"col",
                text:"col2",
                rows: [{}]
            }
        ]
    }
]

The function:

function createHtmlCode(gridArray,level){

    for(var y=0; y<gridArray.length; y++){
        obRow = gridArray[y];
        r+="<div class='row'>";
        arCol = obRow.cols;
        for(var x=0; x<arCol.length; x++){
            obCol = arCol[x];
            r+="<div class='col'>";
            if(obCol.rows){
                createHtmlCode(obCol.rows,level++);
            }
            r+="</div>";
        }
        r+="</div>";
    }

}

r="";
createHtmlCode(gridArray,1);

At the moment the result (r) is:

<div class="row">
    <div class="col">
        <div class="row">
            <div class="col">
            </div>
        </div>
    </div>
</div>

... but it shoud be:

<div class="row">
    <div class="col">
        <div class="row">
            <div class="col">
            </div>
        </div>
    </div>
    <div class="col">
        <div class="row">
        </div>
    </div>
</div>

What am I doing wrong? Thank you in advance for your tips!

Upvotes: 1

Views: 67

Answers (1)

Michael Lorton
Michael Lorton

Reputation: 44386

Hahaha! You have a very subtle (but very common) error.

See here:

    arCol = obRow.cols;

That's the bug, if you look closely.

Got it? Or you want me to spoil it?

The error is: in Javascript, if you don't declare a variable as local, it defaults to global. arCol gets reset in the recursive call!

All the variable declarations should be explicit:

    var arCol = obRow.cols;

Other tips:

  • x and y should be used to indicate spatial information (on the "x-axis" and "y-axis"); use i and j (and if necessary k) for array indices. And declare them as local.
  • do not use global mutable values -- in this example r. Instead have the function return the string
  • never use the same name for a global variable and a formal parameter (gridArray in this case) or a local variable. The computer will not be confused, but you will be.
  • don't put a type name ("array") in a variable name without a specific reason.
  • don't put a simple expression a variable if you are only going to use it once without a good reason

So the corrected code would be

function createHtmlCode(grid,level){
  var r = "";
  for(var i=0; i<grid.length; i++){
    r+="<div class='row'>";
    var arCol = grid[i].cols;
    for(var j=0; j<arCol.length; j++){
      r+="<div class='col'>";
      var rows = arCol[j].rows;
      if(rows){
        r += createHtmlCode(rows,level++);
      }
      r+="</div>";
    }
    r+="</div>";
  }
  return r;
}

console.log(createHtmlCode(myGrid,1));

Upvotes: 2

Related Questions