I want to extract theheaders 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')debuggerlet 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> <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>1 Answer1
Always useconst to declare variables - only uselet 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 uselet but thendon't reassign, it can still be confusing - in professional code, one might think "Why islet 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 aweird property introduced by Internet Explorer (outside of web standards originally) that has a number of odd quirks. Unless you'redeliberately looking to invoke those quirks, it would be a better idea to usetextContent instead to retrieve text from an element.
You can easily distinguish the firsttr from the othertrs 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> <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 usereduce when the accumulator is going to be the same object every time. See:Isreduce 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 atable header. It makes sense for the headers to be<th>s, but the tabledata should probably be<td>s instead.
- \$\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– M A Salman2020-05-20 21:26:29 +00:00CommentedMay 20, 2020 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– M A Salman2020-05-20 22:01:23 +00:00CommentedMay 20, 2020 at 22:01
You mustlog in to answer this question.
Explore related questions
See similar questions with these tags.

