Alex Angelini
Alex Angelini

Reputation: 469

Javascript nested loop

I do not code much in Javascript, but I have the following snippet which IMHO looks horrendous and I have to do this nested iteration quite often in my code. Does anyone have a prettier/easier to read solution?

function addBrowse(data) {
var list = $('<ul></ul>')

for(i = 0; i < data.list.length; i++) {
    var file = list.append('<li class="toLeft">' + data.list[i].name + '</li>')
    for(j = 0; j < data.list[i].children.length; j++) {
        var db = file.append('<li>' + data.list[i].children[j].name + '</li>')
        for(k = 0; k < data.list[i].children[j].children.length; k++)
            db.append('<li class="toRight">' + data.list[i].children[j].children[k].name + '</li>')
    }
}

$('#browse').append(list).show()}

Here is a sample data element

{"file":"","db":"","tbl":"","page":"browse","list":[
  {
     "name":"/home/alex/GoSource/test1.txt",
     "children":[
        {
           "name":"go",
           "children":[
              {
                 "name":"validation1",
                 "children":[

                 ]
              }
           ]
        }
     ]
  },
  {
     "name":"/home/alex/GoSource/test2.txt",
     "children":[
        {
           "name":"go",
           "children":[
              {
                 "name":"validation2",
                 "children":[

                 ]
              }
           ]
        }
     ]
  },
  {
     "name":"/home/alex/GoSource/test3.txt",
     "children":[
        {
           "name":"go",
           "children":[
              {
                 "name":"validation3",
                 "children":[

                 ]
              }
           ]
        }
     ]
  }]}

Thanks a lot

Upvotes: 2

Views: 361

Answers (4)

Stephen
Stephen

Reputation: 18964

If you're using jQuery, it has a fiew methods that can help you out:

function addBrowse(data) {
    var list = $(document.createElement('ul')),
        li = $(document.createElement('li')),
        get_li;

    get_li = function(value, className) {
        className = className === undefined ? '' : className;
        return li.clone().text(value).addClass(className);
    };

    $.each(data.list, function (i, v) {
        list.append(get_li(v.name, 'toLeft'));
        $.each(v.children, function(i, v2) {
            list.append(get_li(v2.name));
            $.each(v2.children, function(i, v3) {
                list.append(get_li(v3.name, 'toRight'));
            });
        });
    });
    $('#browse').append(list).show();
}

Upvotes: 0

winwaed
winwaed

Reputation: 7801

it would be tempting to put the two inner loops in their own functions. This would simplify the code by removing all those nested children references. Although the function calls would cost time, a lot of array referencing would be removed, so you'll probably end up square. more importantly it would be simpler code.

Upvotes: 0

Brian Donovan
Brian Donovan

Reputation: 8400

You can use jQuery's each() function to make this look nicer:

function addBrowse(data) {
  var list = $('<ul></ul>')

  $.each(data.list, function(_, item) {
    var file = list.append('<li class="toLeft">' + item.name + '</li>');
    $.each(item.children, function(_, child) {
      var db = file.append('<li>' + child.name + '</li>');
      $.each(child.children, function(_, grandchild) {
        db.append('<li class="toRight">' + grandchild.name + '</li>');
      });
    });
  });

  $('#browse').append(list).show();
}

A problem here, though, is that you introduce XSS vulnerabilities. You can use jQuery's text function to avoid that, though. Or, as Detroitpro points out, use a templating engine. Also, beware of performance implications when using $.each - it's slower than a for loop, but that won't matter much unless you do it many times.

Upvotes: 2

detroitpro
detroitpro

Reputation: 3913

It might be better to look into a JavaScript templet engine:

Upvotes: 4

Related Questions