Reputation: 1948
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>');
}
}
Upvotes: 1
Views: 10128
Reputation: 74204
If you want to make your code more robust follow these guidelines:
for (var i = 0, l = length; l--; i++)
. The reason for this syntax is explained in fuller detail by Nicholas C. Zakas.idata = data[i];
).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"
).===
instead of ==
and !==
instead of !=
because they don't perform type coercion which might lead to unexpected results..greyBackground { background-color: #EEEEEE; }
and set the className
of each leftCol
paragraph to greyBackground
.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.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! =)
Upvotes: 1
Reputation: 413747
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>');
}
}
Upvotes: 3