2

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

6
  • Have you tried recursion instead of iteration? Is that a possibility or does it have to be a for-loop? Commented Jan 11, 2011 at 18:45
  • I have tried to, but in many of these triple nested loops I am forced to write, there are tiny differences in for each iteration (ie. the toLeft in the example above) which I am not sure how to compensate for with recursion Commented Jan 11, 2011 at 18:46
  • That looks like a perfectly valid loop to me. Are there any specific concerns other than the way it looks? If you don't like it looking "messy" put the loops in a function you call. Commented Jan 11, 2011 at 18:47
  • @Sparafusile, Simply the look, I have these loops littered all over my code, (and all over the code in the underlying server from where this data is being pulled) and I was hoping there was a nicer way to iterate over a triple nested loop like this Commented Jan 11, 2011 at 18:50
  • It looks pretty straightforward to me, and easy to read. And, the best part about this function is that it's already written, so you can just fold it and move on to more interesting problems. Commented Jan 11, 2011 at 18:51

4 Answers 4

4

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

Sign up to request clarification or add additional context in comments.

Comments

2

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.

Comments

0

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.

Comments

0

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();
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.