2
\$\begingroup\$

I want to extract the headers data and column data (not row data) from an HTML table using JavaScript.

Is this a good approach of doing it? And how can I simplify this using jQuery?

let table = document.getElementById('tab')
debugger
let headers = Array.from(table.rows[0].cells).map(x => x.innerText)
let columnData = 
Array.from(table.rows).
      slice(1, table.rows.length).
      map(row =>Array.from(row.cells).map(x => x.innerText))
     .reduce((acc,rowData)=>{
           rowData.forEach((value,index)=>{
           acc[index]= acc[index] || [ ]
           acc[index].push(value) })
      return acc },[])
console.log(headers)
console.log(columnData)
<table id="tab">
  <tr>
    <th>
      Name
    </th>
    <th>
      Age
    </th>
    <th>
      Location
    </th>
  </tr>

  <tr>
    <th>
      Jason
    </th>
    <th>
      22
    </th>
    <th>
      Texas
    </th>
  </tr>
  <tr>
    <th>
      Lawson
    </th>
    <th>
      21
    </th>
    <th>
      Florida
    </th>
  </tr>
  <tr>
    <th>
      Jose
    </th>
    <th>
      25
    </th>
    <th>
      London
    </th>
  </tr>

</table>

\$\endgroup\$
2
\$\begingroup\$

Always use const to declare variables - only use let when you must reassign. This keeps code readable, because then a reader of the code doesn't have to constantly keep in mind that a variable might be reassigned later. (If you use let but then don't reassign, it can still be confusing - in professional code, one might think "Why is let being used here? Was this meant to be reassigned in a section of code that was later removed, or something?)

Array.from accepts an optional mapper function as a second parameter. Any time you have:

Array.from(arrayLike).map(mapper)

you may replace it with

Array.from(arrayLike, mapper)

(If all you're doing is converting an array-like object into an array, some prefer spread syntax because it's even more concise: [...arrayLike])

innerText is a weird property introduced by Internet Explorer (outside of web standards originally) that has a number of odd quirks. Unless you're deliberately looking to invoke those quirks, it would be a better idea to use textContent instead to retrieve text from an element.

You can easily distinguish the first tr from the other trs by using the query string #tab tr:first-child or #tab tr:nth-child(n + 2):

const headers = Array.from(
  document.querySelectorAll('#tab tr:first-child th'),
  th => th.textContent.trim()
);
// Make an empty array for every item in headers:
const data = Array.from(headers, () => []);
for (const tr of document.querySelectorAll('#tab tr:nth-child(n + 2)')) {
  [...tr.children].forEach((th, i) => {
    data[i].push(th.textContent.trim());
  });
}
console.log(headers);
console.log(data);
<table id="tab">
  <tr>
    <th>
      Name
    </th>
    <th>
      Age
    </th>
    <th>
      Location
    </th>
  </tr>

  <tr>
    <th>
      Jason
    </th>
    <th>
      22
    </th>
    <th>
      Texas
    </th>
  </tr>
  <tr>
    <th>
      Lawson
    </th>
    <th>
      21
    </th>
    <th>
      Florida
    </th>
  </tr>
  <tr>
    <th>
      Jose
    </th>
    <th>
      25
    </th>
    <th>
      London
    </th>
  </tr>

</table>

That's already quite simple, IMO. I think adding jQuery to the mix would make things unnecessarily more complicated, not less.

I refactored it out, but I don't think it's good idea to use reduce when the accumulator is going to be the same object every time. See: Is reduce bad? by Google devs. If it's always going to be the same object, it'll be a bit easier to read if that object is declared as a standalone variable in the outer scope.

The HTML is a bit weird. A <th> is a table header. It makes sense for the headers to be <th>s, but the table data should probably be <td>s instead.

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ Hey there @CertainPerformance. This answer is cool . Let me understand and learn from it. Actually i was lazy to write the <tr> again and again.i copied it and changed the values.forgot to make it td. \$\endgroup\$ – M A Salman May 20 at 21:26
  • \$\begingroup\$ Hey i forgot @CertainPerformance.it should output column data actually.not row data.Please run my snippet to understand \$\endgroup\$ – M A Salman May 20 at 22:01

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.