最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

Javascript nested array with nested loops - Stack Overflow

programmeradmin7浏览0评论

I created a nested array as I could so far but I feel like i did it wrong or something does not make sense. Could anyone please have a look and tell me if my array is the way to build nested array. All I want is to create rows under specific title, so I nested data and calling it with nested loops. Maybe theres is a simpler way of achiving it. Here is the code:

var data = [

    {title:'Row Title 1'},

    [{leftCol:'Some text for left column',rightCol:'Some text for right column'},
    {leftCol:'Some text for left column',rightCol:'Some text for right column'},
    {leftCol:'Some text for left column',rightCol:'Some text for right column'}],

    {title:'Row Title 2'},

    [{leftCol:'Some text for left column',rightCol:'Some text for right column'},
    {leftCol:'Some text for left column',rightCol:'Some text for right column'},
    {leftCol:'Some text for left column',rightCol:'Some text for right column'}]

    ];

    for (var i=0, j=data.length; i < j; i++) {

        if(data[i].title != null){
            document.write('<b>'+data[i].title+'</b><br />');
        }

        for(p=0,plen=data[i].length; p<plen;p++){
            document.write('<p style="background:#eee;">'+data[i][p].leftCol+'</p>');
            document.write('<p>'+data[i][p].rightCol+'</p>');       
        }
    }

I created a nested array as I could so far but I feel like i did it wrong or something does not make sense. Could anyone please have a look and tell me if my array is the way to build nested array. All I want is to create rows under specific title, so I nested data and calling it with nested loops. Maybe theres is a simpler way of achiving it. Here is the code:

var data = [

    {title:'Row Title 1'},

    [{leftCol:'Some text for left column',rightCol:'Some text for right column'},
    {leftCol:'Some text for left column',rightCol:'Some text for right column'},
    {leftCol:'Some text for left column',rightCol:'Some text for right column'}],

    {title:'Row Title 2'},

    [{leftCol:'Some text for left column',rightCol:'Some text for right column'},
    {leftCol:'Some text for left column',rightCol:'Some text for right column'},
    {leftCol:'Some text for left column',rightCol:'Some text for right column'}]

    ];

    for (var i=0, j=data.length; i < j; i++) {

        if(data[i].title != null){
            document.write('<b>'+data[i].title+'</b><br />');
        }

        for(p=0,plen=data[i].length; p<plen;p++){
            document.write('<p style="background:#eee;">'+data[i][p].leftCol+'</p>');
            document.write('<p>'+data[i][p].rightCol+'</p>');       
        }
    }
Share Improve this question asked Oct 7, 2011 at 15:46 devjs11devjs11 1,9588 gold badges43 silver badges73 bronze badges 3
  • is there any particular reason you chose to use an array and not JSON? – jbabey Commented Oct 7, 2011 at 16:01
  • No reason. But My code is crushing my mobile application and I feel like i am doing something wrong with my array because if I take away titles "{title:'Row Title 1'}" then it works perfectly. – devjs11 Commented Oct 7, 2011 at 16:07
  • The reason your code breaks is because your nested for loop is not conditional (it checks for the length property on objects {title: 'Row Title 1'} and {title: 'Row Title 2'}). Wrap it in an else scope. – Aadit M Shah Commented Oct 7, 2011 at 16:36
Add a ment  | 

2 Answers 2

Reset to default 3

The structure you're using should be more like this:

var data = [

    {title:'Row Title 1', contents: [

      {leftCol:'Some text for left column',rightCol:'Some text for right column'},
      {leftCol:'Some text for left column',rightCol:'Some text for right column'},
      {leftCol:'Some text for left column',rightCol:'Some text for right column'}

    ],

    // ...
];

That way, each row is an object with a "title" attribute and a "contents" attribute. Your loop would then look like this:

for (var i=0, j=data.length; i < j; i++) {

    if(data[i].title != null){
        document.write('<b>'+data[i].title+'</b><br />');
    }

    for(var p=0, plen=data[i].contents.length; p < plen; p++){
        document.write('<p style="background:#eee;">'+data[i].contents[p].leftCol+'</p>');
        document.write('<p>'+data[i].contents[p].rightCol+'</p>');       
    }
}

If you want to make your code more robust follow these guidelines:

  1. It's always better to initialize for loops like so if you have a length: for (var i = 0, l = length; l--; i++). The reason for this syntax is explained in fuller detail by Nicholas C. Zakas.
  2. Always store variables accessed multiple times in a local variable. It speeds up execution (e.g. idata = data[i];).
  3. Avoid duck typing as far as possible (e.g. data[i].title != null). Check for the type of the variable first. It's slower, but the code is easier to understand and maintain. Try the typeOf function at the bottom of the post (e.g. typeOf(idata) === "Object").
  4. It's usually always better to use === instead of == and !== instead of != because they don't perform type coercion which might lead to unexpected results.
  5. Instead of creating multiple inline styles, create a single class .greyBackground { background-color: #EEEEEE; } and set the className of each leftCol paragraph to greyBackground.
  6. Avoid using document.write. It's slow, causes reflow of the document, and halts loading assets while the page is downloading. The best way to create dynamic content using JavaScript is to use the document.createDocumentFragment method as I'll explain below.
  7. It's always better to create nodes in JavaScript yourself. If you use a string in document.write or element.innerHTML then the browser parses the string and converts it into the nodes anyway. Thus using that method is slower.

This is how I would have written your JavaScript:

var data = [
    "Row Title 1",
    {
        "leftCol": "Some text for left column",
        "rightCol": "Some text for right column"
    }, {
        "leftCol": "Some text for left column",
        "rightCol": "Some text for right column"
    }, {
        "leftCol": "Some text for left column",
        "rightCol": "Some text for right column"
    },
    "Row Title 2",
    {
        "leftCol": "Some text for left column",
        "rightCol": "Some text for right column"
    }, {
        "leftCol": "Some text for left column",
        "rightCol": "Some text for right column"
    }, {
        "leftCol": "Some text for left column",
        "rightCol": "Some text for right column"
    }
];

function typeOf(value) {
    if (value === null) {
        return "null";
    } else if (typeof value === "undefined") {
        return "undefined";
    } else {
        return Object.prototype.toString.call(value).slice(8, -1);
    }
}

var element;
var fragment = document.createDocumentFragment();
var idata;

for (var i = 0, l = data.length; l--; i++) {
    idata = data[i];
    if (typeOf(idata) === "Object") {
        element = document.createElement("p");
        element.className = "greyBackground";
        element.appendChild(document.createTextNode(idata.leftCol));
        fragment.appendChild(element);

        element = document.createElement("p");
        element.appendChild(document.createTextNode(idata.rightCol));
        fragment.appendChild(element);
    } else {
        element = document.createElement("b");
        element.appendChild(document.createTextNode(idata));
        fragment.appendChild(element);

        element = document.createElement("br");
        fragment.appendChild(element);
    }
}

document.body.appendChild(fragment);

Test my page and yours. In all probability mine will execute faster. If you have any doubts feel free to ask me. Cheers! =)

发布评论

评论列表(0)

  1. 暂无评论