Devon Luongo Devon Luongo - 3 months ago 10
Javascript Question

Tables & Javascript: Which formats are best? How do I extract arrays from a table?

Been asked to do define a function that takes an HTML table containing a persons age and weight and returns the mode of all weights for people within a given age range. The function should work with tables of any length. What is the best way to filter rows by a person's age and then convert all qualifying rows in an array (i.e. extract the filtered weight column). I'd like to do the following, although I realize I can't reference an HTML table using square bracket notation. Is there something comparable for HTML tables in JavaScript? I'm interested in learning the best way to work with HTML tables in Javascript in general, the specifics of this problem aren't important.



function birthWeightByAge(ageWeightTbl, rowCount, minVal, maxVal) {
var weightArray = [];
//Traverse table by row
for (var i =0; i < rowCount; i++) {
//Determine age and weight for this row. Can I use this approach with different syntax? Do I need to use a completely different approach?
var age = ageWeightTbl[i][0];
var weight = ageWeightTbl[i][1];
//Check if the baby weight in this row meets the requirements
if (weight > minVal && weight < maxVal) {
//If it does, add the age and weight to our holding arrays
ageArray.push(age);
weightArray.push(weight);
}
}

var weightMode = mode(weightArray);
}





Side Question: Is there a data format that will render on an HTML page, but that is easier to work with in Javascript? If yes, please provide an high level overview of its benefits and how it works.

I've added a sample table as requested:



//Helper function that creates a mock table for testing
function generate_table(rows) {
// get the reference for the body
var body = document.getElementsByTagName("body")[0];

// creates a <table> element and a <tbody> element
var tbl = document.createElement("table");
var tblBody = document.createElement("tbody");

// creating all cells
for (var i = 0; i < rows; i++) {
// creates a table row
var row = document.createElement("tr");

for (var j = 0; j < 2; j++) {
// Create a <td> element and a text node, make the text
// node the contents of the <td>, and put the <td> at
// the end of the table row
var cell = document.createElement("td");
if (j<1) {
var cellText = document.createTextNode(""+Math.round(100*Math.random())+"");
}
else {
var cellText = document.createTextNode(""+Math.round(10*Math.random())+"");
}
cell.appendChild(cellText);
row.appendChild(cell);
}

// add the row to the end of the table body
tblBody.appendChild(row);
}

// put the <tbody> in the <table>
tbl.appendChild(tblBody);
// appends <table> into <body>
body.appendChild(tbl);
// sets the border attribute of tbl to 2;
tbl.setAttribute("border", "2");
}

//Sample Output: {"Mode": 9}




MJH MJH
Answer

Try this: Give your table an id attribute (I added the following line to your "mock table" function: tbl.id = "weightAgeTable";).

Then, call the following function, using that id value as the first argument:

function birthWeightByAge(tableId, rowCount, minVal, maxVal) {
    var weightArray = [];
    var ageArray = [];
    var tbl = document.getElementById(tableId);

    //Traverse table by row
    for (var i =0; i < rowCount; i++) {

        //Determine age and weight for this row
        var weight = tbl.rows[i].cells[0].innerHTML; //var weight = ageWeightTbl[i][1];
        var age = tbl.rows[i].cells[1].innerHTML; //var age = ageWeightTbl[i][0];

        //Check if the baby weight in this row meets the requirements
        if (weight > minVal && weight < maxVal) {
            //If it does, add the age and weight to our holding arrays
            ageArray.push(age);
            weightArray.push(weight);
        }
    }

    console.log(weightArray); // var weightMode = mode(weightArray);
}

I don't have your mode function, so I commented it and output the array to the console instead, for demo purposes.

Also, I think your "mock table" function may have reversed the columns, which is why my .cells numbers are reversed from yours.