skip to Main Content
var MyArray = [['Cats', ['Lion','Tiger','Leopard']], ['Dogs', ['Wolf','Pug']], ['Reptiles', ['Snake','Gecko','Lizard','Triceratops']]];

var MyTable = document.getElementById("results");
const headerRow = document.createElement("tr");
MyTable.appendChild(headerRow);
for(var i=0;i<MyArray.length;i++) {
    const newCell = document.createElement("th");
    newCell.textContent = MyArray[i][0];
    headerRow.appendChild(newCell);
    for (const datum of MyArray[i][1]) {
        const newRow = document.createElement("tr");
        MyTable.appendChild(newRow);
        const newCell = document.createElement("td");
        newCell.textContent = datum;
        newRow.appendChild(newCell);
    }
}
<table id='results' border=1></table>

I’m currently trying to turn an array of arrays in Javascript into an HTML table of results. I have it kinda working, but my JS skills with arrays aren’t enough to get the exact results I’m after; any help would be greatly appreciated!

You can see in the snippet that my code is iterating through that array of arrays, extracting the [0] data from each array (the animal class) and building a table with a header row just fine, but the actual data ([1] of each array) is all getting dumped into the first column only, with each entry being a new row.

How do I get the code to put these into separate cells of the new table, bearing in mind the child arrays are all different lengths?

My code is producing a table with all the data in the first column only. What should happen is it produces a table like this:

Cats Dogs Reptiles
Lion Wolf Snake
Tiger Pug Gecko
Leopard Lizard
Triceratops

Any guidance gratefully accepted!

4

Answers


  1. Chosen as BEST ANSWER

    Thank you everyone for your help and advice on this. My JS skills are still very much in development, so I'm going to take a little time going through the working examples to improve my knowledge and understand why they work and where my original was going wrong!


  2. My advice on this would be to avoid using tuples like this. Here what you are processing is called a tuple array ['familyName', ['members']] and is a bad practice. Generally speaking, in JS, you should work with objects as much as possible.

    JavaScript offers a lot of tools to help you work with objects and arrays. See the code below where I’m using a reduce function to format the array into an object and the Math.max function to find the largest family length before iterating the whole dataset.

    const myResults = [['Cats', ['Lion','Tiger','Leopard']], ['Dogs', ['Wolf','Pug']], ['Reptiles', ['Snake','Gecko','Lizard','Triceratops']]];
    
    // Format the data into an array of objects: [{name: 'string', members: ['string']}]
    const families = myResults.reduce(
      (acc, next) => [...acc, {name: next[0], members: next[1]}]
    , []);
    
    // Get table reference
    const myTable = document.getElementById("results");
    
    // Create headers
    families.forEach(family => {
      const header = document.createElement("th");
      header.textContent = family.name;
      myTable.appendChild(header);
    });
    
    // Largest family length
    const maxLength = Math.max(...families.map(family => family.members.length));
    
    // Create cells
    for (let i = 0; i < maxLength; i++) {
      const row = document.createElement("tr");
      myTable.appendChild(row);
      // Extract a row of animals for line 'i'
      const animals = families.map(family => family.members[i]);
      animals.forEach(animal => {
        const cell = document.createElement("td");
        cell.textContent = animal;
        row.appendChild(cell);
      });
    }
    <table id="results" border="1"></table>
    Login or Signup to reply.
  3. Is this what you are looking for?

    const values = [
      ['Cats',["Lion","Tiger","Leopard"]],
      ['Dogs',["Wolf","Pug"]],
      ['Reptiles',["Snake","Gecko","Lizard","Triceratops"]]
    ];
    
    const table = document.querySelector("#myList");
    const headers = table.querySelector("THEAD");
    const body = table.querySelector("TBODY");
    
    const maxCols = values.length;
    let maxRows = 0;
    values.forEach((col) => {
        if (col[1].length > maxRows) {
            maxRows = col[1].length;
        } 
    });
    
    // First loop to create table headers
    for(let colIndex = 0; colIndex < maxCols; colIndex++) {
        const headerText = values[colIndex][0]; // Get the title
        const th = document.createElement("TH");
        th.textContent = headerText;
        headers.appendChild(th);
    }
    
    // Second loop to create all rows and look for a value on each column of that row
    for (let rowIndex = 0; rowIndex < maxRows;  rowIndex++) {
        const col = document.createElement("TR");
        for(let colIndex = 0; colIndex < maxCols; colIndex++) {
            const list = values[colIndex][1]; // Get the elements list
            const blocText = list[rowIndex] || ""; // Get the value at row or empty string
            const td = document.createElement("TD");
            td.textContent = blocText;
            col.appendChild(td);
        }
        body.appendChild(col);
    }
    <table id="myList">
      <thead></thead>
      <tbody></tbody>
    </table>
    Login or Signup to reply.
  4. As others have already said, refactoring the input array would be the best solution. Going of off what you have provided the below solution should work for you.

    var MyResults = [['Cats', ['Lion','Tiger','Leopard']], ['Dogs', ['Wolf','Pug']], ['Reptiles', ['Snake','Gecko','Lizard','Triceratops']]];
    
    // Gets the maximum number of members within the familes
    max_dimension = Math.max(...MyResults.map(el => el[1].length));
    
    var MyTable = document.getElementById("results");
    const headerRow = document.createElement("tr");
    MyTable.appendChild(headerRow);
    
    // Creates the rows required for the family members
    for (let x = 0; x < max_dimension; x++) {
        const newRow = document.createElement("tr");
        MyTable.appendChild(newRow);
    }
    
    for(let i=0;i<MyResults.length;i++) {
        // Creates the header
        const newCell = document.createElement("th");
        newCell.textContent = MyResults[i][0];
        headerRow.appendChild(newCell);
        // Adds the family member if applicable
        for (let x = 0; x < max_dimension; x++) {
            const newCell = document.createElement("td");
            newCell.textContent = MyResults[i][1][x];
            MyTable.children[x+1].appendChild(newCell);
        }
    }
    <table id='results'></table>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search